一、sed编辑器的介绍
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中, 称为"模式空间"(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后, 把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
1.sed 流编辑器的工作过程
sed的工作流程主要包括读取、执行和显示三个过程:
读取: sed从输入流 (文件、管道、标准输入) 中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space )。
执行: 默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,
否则sed命令将会在所有的行上依次执行。
显示: 发送修改后的内容到输出流。在发送数据后,
模式空间将会被清空。在所有的文件内容都被处理完成之前,上述过程将重复执行,
直至所有内容被处理完。
在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。
注意:默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非使用"sed -i"修改源文件、或使用重定向输出到新的文件中。
2. 解决sed命令处理容量过大,或则内容过多的而导致执行效率慢的方法
解决方案一(推荐用法):
使用split命令进行文件分割(例如文件如果是百万行,就创建一个单独的目录将文件分割为一百个为一万行的文本)
解决方案二:
使用cat 文件名|sed 处理
(但是该方案只能针对中大型的文件文本,如果文本量过大,处理效果不好)
3. sed命令格式与选项操作符
sed命令的操作符
s
:替换,替换指定字符。d
:删除,删除选定的行。a
:增加,在当前行下面插入一行指定内容。i
:插入,在选定行上面插入一行指定内容。c
:替换,将选定行替换为指定内容。y
:字符转换,转换前后的字符长度必须相同。p
:打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以 ASCII 码输出。其通常与"-n"选项一起使用。\=
:打印行号。l
(小写L):打印数据流中的文本和不可打印的ASCII字符(比如结束符$、制表符\t)r
:扩展正则表达式
基本操作格式:
bash
sed -e '操作' 文件1 文件2
sed -e '操作' 文件1 文件2
sed -f 脚本文件 文件1 文件2
sed -i -e '操作' 文件1 文件2
bash
查看
sed -n -e '行号p'
sed -n -e '起始行号,终止行号p' # $可代表最后一行
sed -n -e '1~2p' #从第一行开始,行号递增2输出
sed -n -e '/字符串/p'
sed -n -r -e '/正则表达式/p'
删除
sed -e '行号区间d'
sed -e '/字符串/d'
sed -r -e '/正则表达式/d'
替换 s(字符串替换) c(整行替换)
sed -e '行号区间 s/OLD/NEW/g' sed -n -e '行号区间 s/OLD/NEW/gp' #只打印被修改的行
sed -e '/字符串/ s/OLD/NEW/g'
sed -r -e '/正则表达式/ s/OLD/NEW/g'
sed -r -e 's/(xxx)(xxx)(xxx)/\3\2\1/'
sed -e 's#OLD#NEW#g'
执行多条命令的格式:
方式一:
bash
sed -e '操作1' -e '操作2' 文件
sed -n -e '/^r/p' -e '/^b/p' /etc/passwd
方式二:
bash
sed -e '操作1;操作2' 文件
sed命令的常用选项
\-e
或--expression=
: 表示用指定命令来处理输入的文本文件,只有一个操作命令时可省略,一般在执行多个操作命令使用
\-f
或--file=
:表示用指定的脚本文件来处理输入的文本文件。
\-h
或--help
:显示帮助。
\-i
直接修改目标文本文件 慎用
\-n
仅显示script处理后的结果
4. sed最为核心的功能是增删改查
1.sed命令的打印功能
bash
\[root@localhost opt\]# sed ''
\[root@localhost ~\]#sed '' /etc/fstab #查看文件内容
\[root@localhost opt\]# sed '' < /etc/fstab #可以支持重定向输入
\[root@localhost opt\]# cat /etc/passwd |sed '' #也可以支持管道符
2.默认打印方式:
bash
\[root@www rh\]# sed -e 'p' test1.txt --sed有一个默认输出,加上P,会打印两行
123
123
345
345
789
789
000
000
\[root@www rh\]# sed -n 'p' test1.txt -- -n禁止了默认输出,就只有一行
123
345
789
000
\[root@localhost opt\]# ifconfig ens33|sed -n 2p #打印第二行
inet 192.168.233.21 netmask 255.255.255.0 broadcast 192.168.233.255
打印时对行号的操作
\[root@localhost sed\]#sed -n '=' test1.txt ---只显示行号
\[root@localhost sed\]#sed -n '=;p' test1.txt ---显示行号和每行的内容
3. sed命令的寻址打印:
方式一:按照行号寻求内容
bash
\[root@localhost sed\]#sed -n '1p' test1.txt --打印第一行
\[root@localhost sed\]#sed -n '4p' test1.txt --打印第四行
\[root@localhost sed\]#sed -n '$p' test1.txt --打印最后一行
方式二:进行行号范围区间的打印
bash
\[root@localhost sed\]#sed -n '1,3p' test1.txt --打印1-3行
\[root@localhost sed\]#sed -n '5,$p' test1.txt --打印第五行到最后一行
\[root@localhost sed\]#sed -n '2,+2p' test1.txt ---打印第二行+两行的内容,相当于2,4p
\[root@localhost opt\]#sed -n '3p;5p' test1.txt ---输出第三行和第五行
方式三:指定间隔打印
bash
\[root@localhost sed\]#sed -n -e '2p' -e'$p' test1.txt ---打印第二行和最后一行
\[root@localhost sed\]#sed -n -e '2p' -e'3p' test1.txt ---打印第二行和第三行
方式四:对奇数行和偶数行的打印
bash
\[root@localhost sed\]#sed -n 'n;p' test1.txt ---打印偶数的行
\[root@localhost sed\]#sed -n 'p;n' test1.txt ---打印奇数的行
n在p前面,跳过一行,打印下一行,就是偶数行;在后面,就是打印第一行,然后跳过一行,形成奇数行
4. 文本模式过滤行内容
方式一:对包含的字符串进行过滤打印
bash
\[root@localhost sed\]#sed -n '/o/p' test1.txt ---包含o的所有行
\[root@localhost sed\]#sed -n '/th/p' test1.txt ---包含th的所有行
方式二:应用基础正则表达式进行打印
bash
\[root@localhost sed\]#sed -n '/^root/p' /etc/passwd --以root为开头的所有内容,全文本搜索
\[root@localhost sed\]#sed -n '/bash$/p' /etc/passwd --以bash结尾的所有内容,全文本搜索
\[root@localhost sed\]#sed -n '4,/bash$/p' /etc/passwd --从第四行开始,一直打印到第一个以bash为结尾的所在行
方式三:使用扩展正则表达式进行打印
注意:
bash
sed -r 支持扩展正则表达式。同时在 使用{n}、{n,}、{n,m}时,括号{}前不需要加反斜杠\\ 。
\[root@localhost sed\]# sed -r -n '/(99:){2,}/p' /etc/passwd ---包含有两个99:的内容所在行
\[root@localhost sed\]# sed -r -n '/^root|bash$/p' /etc/passwd ---包换以root开头,或者以bsah结尾的内容所在行
5. sed的删除操作:
bash
sed -i 时会对文本进行实际操作(建议对目标文件先进行备份,再进行操作)
通过行号进行删除
\[root@localhost sed\]#sed 'd' test1.txt ---删除所有,什么也不打印
\[root@localhost sed\]#sed -n '3d;p' test1.txt ---删除第三行,打印剩余的所有内容
\[root@localhost sed\]#sed -n '5,8d;p' test1.txt ---删除5到8行,打印剩余的所有内容
\[root@localhost sed\]#sed -n '5,$d;p' test1.txt ---删除5到最后一行行,打印剩余的所有内容
\[root@localhost sed\]#sed '4,6!d' test1.txt ---除了4-6行,其他的全部删除
如果要生效:sed -i -n
6. 匹配字符串内容删除
bash
\[root@localhost sed\]#sed '/one/d' test1.txt ---删除包含one的行
\[root@localhost sed\]#sed '/one/,/six/d' test1.txt ---删除one-six的行
\[root@localhost sed\]#sed '/one/,/six/!d' test1.txt ---除了one-six的行,其余的全部删除,反向删除
\[root@localhost sed\]#sed '/six/!d' test1.txt ---除了six的行,其余的全部删除,反向删除
7.字符串搭配正则进行删除:
bash
\[root@localhost sed\]#sed '/^$/d' test1.txt ---通过^$,来删除空行;
8.删除空行的三种方法:
bash
grep -v "^$" test1.txt 过滤出非空行
cat test1.txt |tr -s "\\n" 压缩换行符
sed '/^$/d' test1.txt 删除空行
9.sed命令替换:
格式:
行范围 s/旧字符串/新字符串/替换标记
替换标记:
数字:表明新字符串将替换第几处匹配的地方
g
:表面新字符串将会替换所有匹配的地方
p
:打印与替换命令匹配的行,与-n一起使用
w
文件:将替换的结果写入文件中
sed命令的替换中:
s
:替换字符串
c
:整行替换
y
:字符替换,替换前后的字符串长度必须相同
bash
\[root@localhost sed\]#sed -n 's/root/test/2p' /etc/passwd --指定第二个root,替换为了test
\[root@localhost sed\]#sed -n 's/root/test/gp' /etc/passwd --所有的root都替换为test
\[root@localhost sed\]#sed -n '/^root/ s/^/#/p' /etc/passwd --以root开头开始处理,把开头为空的替换为#,注释掉
字母字符进行大小写的替换:
bash
\[root@localhost sed\]#sed 's/\[A-Z\]/\\l&/g' test1.txt ---将大写全部转换为小写,
l&是转换小写的一种特殊的符号,前面要加转义符"\\"
\[root@localhost sed\]#sed 's/\[a-z\]/\\u&/' test1.txt ---把首字母替换成大写,
u&是转换首字母大写的一种特殊的符号,前面要加转义符"\\"
\[root@localhost sed\]#sed 's/\[a-z\]/\\U&/g' test1.txt ---末尾加上了一个g,全部转换成大写
整行替换:
bash
\[root@localhost sed\]# sed '/ONE/c 22' test1.txt
\[root@localhost sed\]# sed '/TWO/c TEST' test1.txt
单字符的替换
使用y,是对单个字符进行替换,每个字符需要一一对应,不是整体替换。前后字符串长度需要一致,不然会报错
只要有匹配的单字符会全部替换
bash
\[root@localhost sed\]# sed 'y/TH/12/' test1.txt
sed命令的增加:
a:在下一行添加内容
i:在上一行插入内容
r:在行后读入文件内容
bash
\[root@localhost sed\]# sed '/three/a 123' test1.txt #行后
\[root@localhost sed\]# sed '/three/i 123' test1.txt #上一行
\[root@test1 opt\]# sed '/three/r test.sh' 123.txt #当前行的下一行
\[root@localhost sed\]# sed '$r test2.txt' test1.txt ---先读取test1内容,然后再test2的末行插入test2的所有内容
\[root@localhost opt\]# sed '$a 123' 123.txt #在123.txt的文件最后一行插入123
oneoneone
oneoneone
twotwotwo
oneoneone
twotwotwo
oneoneone
twotwotwo
123
\[root@localhost opt\]# sed '$i 123' 123.txt #在123.txt的文件最后后面的行中插入123
oneoneone
oneoneone
twotwotwo
oneoneone
twotwotwo
oneoneone
123
twotwotwo
<br/>
sed命令中字符串和字符的位置交换
\[root@localhost opt\]# echo ky29ztt | sed -r 's/(ky29)(ztt)/\\2\\1/'
yhtky27
\[root@localhost opt\]# echo ky27yhtdxl | sed -r 's/(ky27)(yht)(dxl)/\\3\\2\\1/'
dxlyhtky27
\[root@localhost opt\]# echo ky27yhtdxl | sed -r 's/(ky27)(yht)(dxl)/\\2\\1/'
yhtky27
\[root@localhost opt\]# echo ky27yhtdxl | sed -r 's/(ky27)(yht)(dxl)/\\3\\1/'
dxlky27
\[root@localhost opt\]# echo ky27yhtdxl | sed -r 's/(ky27)(yht)(dxl)/\\3\\2/'
dxlyht
\[root@localhost sed\]#echo 123abc|sed -r 's/(.)(.)(.)(.)(.)(.)/\\6\\5\\4\\3\\2\\1/' #前面的点表示字符位置,后面的数字表示对应的交换顺序
sed -f 指定命令来对第二个文件的行进行处理。
```bash
\[root@localhost opt\]# cat 123.txt
/IPADDR=192.168.233.21/c IPADDR=10.10.10.10
\[root@localhost opt\]# cat 456.txt
IPADDR=192.168.233.21
\[root@localhost opt\]# sed -f 123.txt 456.txt
IPADDR=10.10.10.10
\[root@localhost opt\]# cat ky27.txt
s/ /\_/g
\[root@localhost opt\]# cat ky27sed.txt
hello world
yht dxl
\[root@localhost opt\]# sed -f ky27.txt ky27sed.txt
hello_world
yht_dxl
二、awk:
在 Linux/UNIX 系统中,awk 是一个功能强大的编辑工具,逐行读取输入文本,默认以空格或tab键作为分隔符作为分隔,并按模式或者条件执行编辑命令。AWK信息的读入也是逐行指定的匹配模式进行查找,对符合条件的内容进行格式化输出或者过滤处理.
1.awk的工作过程:
- 第一步:执行BEGIN{action;... }语句块中的语句。
- 第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ action;... }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
- 第三步:当读至输入流末尾时,执行END{action;...}语句块
2.工作原理:
sed命令常用于一整行的处理,而awk比较倾向于将一行分成多个"字段"然后再进行处理, 且默认情况下字段的分隔符为空格或 tab 键。 awk 执行结果可以通过 print 的功能将字段数据打印显示
awk的基本格式及其内置变量:
bash
awk 选项 '模式或条件 {操作}' 文件1 文件2...
-F
· "分隔符" 指明输入时用到的字段分隔符,默认的分隔符是若干个连续空白符
-v
(小v) var=value 变量赋值
{ }
外指定条件,{ }内指定操作。
用逗号指定连续的行,用 || 指定不连续的行。&&表示"且"。
awk {print $1,$2,$3}
内置变量,不能用双引号括起来,不然系统会把它当成字符串。
内置变量
- $0: 当前处理的行的整行内容 打印所有
- $n: 当前处理行的第n个字段(第n列)
- NR: 当前处理的行的行号(序数)
- NF: 当前处理的行的字段个数。$NF代表最后一个字段
- FS: 列分割符。指定每行文本的字段分隔符,输入内容的分隔符,
- 默认为空格或制表位。与"-F"作用相同 用-F可以不加单引号 -F:,用FS必须用=""
- OFS:输出内容的列分隔符
- FILENAME:被处理的文件名
- RS: 行分隔符。awk从文件中读取资料时, 将根据RS的定义把资料切割成许多条记录,而awk一次仅读入一条记录进行处理。预设值是"\n"
3.基本打印用法:
awk 截取行内容的字段
bash
-F '字段分隔符' #指定字段分隔符,默认为空格
awk -F '分隔符' '条件表达式 {操作}' 文件
awk -F '分隔符' 'NR==n {print $0}' 文件 #输出 第n行的 整行内容
awk -F '分隔符' 'NR==n {print $1,$4,$NF}' 文件 #输出 第n行的 第一个字段 第四个字段 最后一个字段的内容
awk -F '分隔符' 'NR==n,NR==m {print $0}' 文件 #输出 第n行到第m行的 整行内容
awk -F '分隔符' 'NR>=n&&NR<=m {print $0}' 文件
awk -F '分隔符' 'NR==n||NR==m {print $0}' 文件 #输出 第n行和第m行的 整行内容
awk -F '分隔符' '/字符串/{print $0}' 文件 #输出 包含指定字符串的 整行内容
awk -F '分隔符' '/正则表达式/{print $0}' 文件 #输出 匹配正则表达式的 整行内容
awk -F '分隔符' '$1=="XX" {print $0}' 文件 #输出 第一个字段为XX的 整行内容
awk -F '分隔符' '$0~"XX" {print $0}' 文件 #输出 行内容包含XX的 整行内容
操作符 ==(等于) !=(不等于) >=(大于等于) >(大于) <=(小于等于) <(小于) ~(包含) !~(不包含)
awk的 BEGIN END 模式
awk 'BEGIN {...}; 条件{....}; END {....}' 文件
BEGIN {...} 表示处理文件前要执行的操作
条件{....} 表示对匹配满足条件的文件行内容要执行的操作
END {....} 表示处理完文件所有行后要执行的操作