正则三剑客(二)
二、sed工具的使用
1、打印某行
sed -n ‘n’p filename,单引号内的n是一个数字,表示第几行,-n为只显示打印的行,示例如下:
# sed -n '3'p test.txt //打印打三行 operator:x:11:0:operator:/rooot:sbin/nologin # sed -n '1,$'p test.txt //把所有行都打印出来,$表示行末
# sed -n '1,3'p test.txt //也可以打印一个区间 rot:x:0:0:/rot:/bin/bash operator:x:11:0:operator:/root:sbin/nologin operator:x:11:0:operator:/rooot:sbin/nologin
2、打印包含某个字符串的行
# sed -n '/root/'p test.txt //“//”符号表示转义 operator:x:11:0:operator:/root:sbin/nologin
grep中使用的特殊字符(^、$、.、*)等,同样也可以在sed工具中使用,示例如下:
# sed -n '/^1/'p test.txt //打印1开头的行 111111111111111111111111111111111 # sed -n '/in$/'p test.txt //打印结尾是in的行 operator:x:11:0:operator:/root:/sbin/nologin operator:x:11:0:operator:/rooot:/sbin/nologin # sed -n '/r..o/'p test.txt //把r与o之间任意的字符的行都打印 operator:x:11:0:operator:/root:/sbin/nologin operator:x:11:0:operator:/rooot:/sbin/nologin rooooot:x:0:0:/roooooot:/bin/bash # sed -n '/ooo*/'p test.txt //表示有2个或2个以上的o的行全部 打印 operator:x:11:0:operator:/root:/sbin/nologin operator:x:11:0:operator:/rooot:/sbin/nologin rooooot:x:0:0:/roooooot:/bin/bash 加上-e选项可以实现多个行为,示例如下: # sed -e '1'p -e '/111/'p -n test.txt //表示打印第一行和含有字符串1的行 rot:x:0:0:/rot:/bin/bash 111111111111111111111111111111111
3、删除某些行
# sed '1'd test.txt //删除第一行 operator:x:11:0:operator:/root:/sbin/nologin operator:x:11:0:operator:/rooot:/sbin/nologin rooooot:x:0:0:/roooooot:/bin/bash 111111111111111111111111111111111 Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # sed '1,3'd test.txt //删除1-3行 rooooot:x:0:0:/roooooot:/bin/bash 111111111111111111111111111111111 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
参数d表示删除的动作,它不仅可以删除指定的单行以及多行,而且可以删除匹配某个字符的行,还可以删除某一行开始到最后一行的所有行,不过这些操作都只是显示在屏幕上的,文档还是好好的。
4、替换字符或者字符串
# sed '1,2s/ot/to/g' test.txt //表示把第1,2行的ot都替换成to rto:x:0:0:/rto:/bin/bash operator:x:11:0:operator:/roto:/sbin/nologin operator:x:11:0:operator:/rooot:/sbin/nologin rooooot:x:0:0:/roooooot:/bin/bash 111111111111111111111111111111111 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
s表示替换的动作,g表示全局替换,不加g只替换本行出现的第一个。
除了/可以做分隔符以外,还可以使用#和@,示例如下:
# sed 's#ot#to#g' test.txt rto:x:0:0:/rto:/bin/bash operator:x:11:0:operator:/roto:/sbin/nologin operator:x:11:0:operator:/rooto:/sbin/nologin rooooto:x:0:0:/roooooto:/bin/bash 111111111111111111111111111111111 Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # sed 's@ot@to@g' test.txt rto:x:0:0:/rto:/bin/bash operator:x:11:0:operator:/roto:/sbin/nologin operator:x:11:0:operator:/rooto:/sbin/nologin rooooto:x:0:0:/roooooto:/bin/bash 111111111111111111111111111111111 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
替换文档中的数字或者字母,示例如下:
# sed 's/[0-9]//g' test.txt //[0-9]表示任意数字,这里是把数字换成空白 rot:x:::/rot:/bin/bash operator:x:::operator:/root:/sbin/nologin operator:x:::operator:/rooot:/sbin/nologin rooooot:x:::/roooooot:/bin/bash aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # sed 's/[0-9]/d/g' test.txt //这里是把所有数字都换成d rot:x:dd:dd:/rot:/bin/bash operator:x:dddd:dd:operator:/root:/sbin/nologin operator:x:dddd:dd:operator:/rooot:/sbin/nologin rooooot:x:dd:dd:/roooooot:/bin/bash ddddddddddddddddddddddddddddddddd aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # sed 's/[a-zA-Z]//g' test.txt //把所有字母都不显示 ::0:0:/:// ::11:0::/:// ::11:0::/:// ::0:0:/:// 111111111111111111111111111111111
5、调换两个字符串的位置
# sed 's/\(rot\)\(.*\)\(bash\)/\3\2\1/' test.txt bash:x:0:0:/rot:/bin/rot operator:x:11:0:operator:/root:/sbin/nologin operator:x:11:0:operator:/rooot:/sbin/nologin rooooot:x:0:0:/roooooot:/bin/bash 111111111111111111111111111111111 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # sed -r 's/(rot)(.*)(bash)/\3\2\1/' test.txt //-r可以省略转义字符 bash:x:0:0:/rot:/bin/rot operator:x:11:0:operator:/root:/sbin/nologin operator:x:11:0:operator:/rooot:/sbin/nologin rooooot:x:0:0:/roooooot:/bin/bash 111111111111111111111111111111111 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
()在sed中属于特殊符号所以每个括号前都需加一个转义字符\,这里(rot\)相当于1,(.*)则表示rot与bash中间所有的内容,相当于2,(bash\)相当于3,
后面的\3\2\1则表示对应替换的内容,意思就1换成3,2换成2,3换成1,举个例子更容易理解些:
# sed -r 's/(rot)(.*)(bash)/\3\2\3/' test.txt bash:x:0:0:/rot:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin operator:x:11:0:operator:/rooot:/sbin/nologin rooooot:x:0:0:/roooooot:/bin/bash 111111111111111111111111111111111 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
在某一行前后增加指定内容,示例如下:
# sed 's/^.*$/123&/' test.txt 123rot:x:0:0:/rot:/bin/bash 123operator:x:11:0:operator:/root:/sbin/nologin 123operator:x:11:0:operator:/rooot:/sbin/nologin 123rooooot:x:0:0:/roooooot:/bin/bash 123111111111111111111111111111111111 123aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
^.*$表示所有内容,123&则表示在行前加入指定的内容。
6、直接修改文件的内容
# sed -i 's/ot/to/g' test.txt # cat test.txt rto:x:0:0:/rto:/bin/bash operator:x:11:0:operator:/roto:/sbin/nologin operator:x:11:0:operator:/rooto:/sbin/nologin rooooto:x:0:0:/roooooto:/bin/bash 111111111111111111111111111111111 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
修改文件之前做好备份,以免改错。
7、练习题
(1)把/etc/password复制到/root/test.txt,用sed打印所有行
(2)打印test.txt的第3行到第10行
(3)打印test.txt中包含root的行
(4)删除test.txt的第15行以及后面的所有行
(5)删除test.txt中包含bash的行
(6)将test.txt中的root替换为toor
(7)将test.txt中的/sbin/nologin替换为/bin/login
(8)删除test.txt中第5行到第10行中的所有数字
(9)删除test.txt中所有的特殊字符(除了数字和大小写字母)
(10)把test.txt中的第一个单词和最后一个单词调换位置
(11)把test.txt中第一个数字移动到本行末尾
(12)在test.txt第20行到最后一行最前面加aaa:
答案: (1)# cp /etc/passwd /root/test.txt # sed -n '1,$'p test.txt (2)# sed -n '3,10'p test.txt (3)# sed -n '/root/'p test.txt (4)# sed '15,$'d test.txt (5)# sed '/bash/'d test.txt (6)# sed 's/root/toor/g' test.txt (7)# sed 's#sbin/nologin#bin/login#g' test.txt (8)# sed '5,10s/[0-9]//g' test.txt (9)# sed 's/[^0-9a-zA-Z]//g' test.txt (10)# sed -r 's/(^[a-zA-Z]+)([^a-zA-Z].*[^a-zA-Z])([a-zA-Z]+$)/\3\2\1/' test.txt (11)# sed -r 's/(^[^0-9]*)([0-9]+)([^0-9].*$)/\3\2\1/' test.txt (12)# sed '20,$s/^.*$/aaa:&/' test.txt