grep工具的功能其实还不够强大,grep实现的只是查找功能,而它却不能实现把查找的内容替换掉。vim可以查找也可以替换,但是只局限于在文本内部来操作,而不能输出到屏幕上。sed和awk工具就能实现把替换的文本输出到屏幕上的功能,而且还有其他更丰富的功能。sed和awk都是流式编辑器,是针对文档的行来操作的。
语法:
sed [options] '命令' file(s)
sed [options] -f scriptfile file(s)
1.打印某行
sed -n 'n'p filename 单引号内的n是一个数字,表示第几行:
[root@greg-01 ~/sed]# sed -n '2'p passwd
bin:x:1:1:bin:/bin:/sbin/nologin
-n选项作用:只显示要打印的行,无关紧要的内容不显示
要想把所有行都打印出来可以使用 sed -n '1,$'p filename
也可以指定一个区间: sed -n '1,3'p filename
2.打印包含某个字符串的行
grep中使用的特殊字符,如 ^ $ . * 等同样也能在sed中使用
[root@greg-01 ~/sed]# sed -n '/root/'p passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@greg-01 ~/sed]# sed -n '/r*t/'p passwd
3.-e可以实现多个行为
[root@greg-01 ~/sed]# sed -e '1'p -e '/111/'p -n sed1.txt
root:x:0:0:root:/rooot:/bin/bashlooov
11111111111111111111111111111
4.I不区分大小写
5. 删除某行或者多行
sed '1'd passwd
sed '1,3'd passwd
'd' 这个字符就是删除的动作了,不仅可以删除指定的单行以及多行,而且还可以删除匹配某个字符的行,另外还可以删除从某一行一直到文档末行。
不过,这个操作仅仅是在显示屏幕上并不显示而已,文档还好好的。
6.替换字符或字符串
's' 就是替换的命令, 'g' 为本行中全局替换,如果不加 'g' 只换该行中出现的第一个。
sed '1,2s/ot/to/g' sed1.txt
-n选项和p命令一起使用表示只打印那些发生替换的行:
sed -n 's/ot/to/p' sed1.txt
除了可以使用 '/' 作为分隔符外,还可以使用其他特殊字符例如 '#' 或者 '@' 都没有问题。
sed 's#ot#txxxxxxxxxxx#g' sed1.txt
使用正则表达式把数字替换为空,等于删除所有数字
sed 's/[0-9]//g' sed1.txt
sed 's/[a-zA-Z]//g' sed1.txt
7.调换两个字符串的位置
用 () 把所想要替换的字符括起来成为一个整体,因为括号在sed中属于特殊符号,所以需要在前面加脱意字符 , 替换时则写成 '1', ''2', ''3' 的形式。
[root@greg-01 ~/sed]# sed -r 's/([^:]+):(.*):([^:]+)/\3:\2:\1/' sed1.txt
/bin/bashlooov:x:0:0:root:/rooot:root
/sbin/nologin:x:1:1:bin:/bin:bin
/sbin/nologin:x:2:2:daemon:/sbin:daemon
roooot:x:3:4:adm:/var/adm:/sbin/nologin:operator
11111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaa
\(..\) 用于匹配子串,对于匹配到的第一个子串就标记为 \1,依此类推匹配到的第二个结果就是 \2。使用-r可以省略转义字符。
除了调换两个字符串的位置外,还可以在某一行前或者后增加指定内容。
& 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。
8.直接修改文件的内容
直接编辑文件选项-i,sed -i 's/ro/RORORORO/g' sed1.txt
sed总结
sed元字符(正则表达式)
^ 匹配行开始,如:/^sed/匹配所有以sed开头的行。
$ 匹配行结束,如:/sed$/匹配所有以sed结尾的行。
. 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。
* 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[] 匹配一个指定范围内的字符,如/[ss]ed/匹配sed和Sed。
[^] 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
\(..\) 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
& 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。
\< 匹配单词的开始,如:/\ 匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行。
x\{m\} 重复字符x,m次,如:/0\{5\}/匹配包含5个0的行。
x\{m,\} 重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行。
x\{m,n\} 重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行。
练习:
把/etc/passwd 复制到/sed/passwd,用sed打印所有行
打印passwd的3到10行
sed -n '3,10'p passwd
打印passwd 中包含 ‘root’ 的行
sed -n '/root/'p passwd
删除passwd 的15行以及以后所有行
sed '15,$'d passwd
删除passwd中包含 ‘bash’ 的行
sed '/bash/'d passwd
替换passwd 中 ‘root’ 为 ‘toor’
sed 's/root/toor/g' passwd
替换passwd中 ‘/sbin/nologin’ 为 ‘/bin/login’
sed 's#sbin/nologin#bin/login#g' passwd
删除passwd中5到10行中所有的数字
sed '5,10s/[0-9]//g' passwd
删除passwd 中所有特殊字符(除了数字以及大小写字母)
sed 's/[^0-9a-zA-Z]//g' passwd
把passwd中第一个单词和最后一个单词调换位置
sed 's/\(^[a-zA-Z][a-zA-Z]*\)\([^a-zA-Z].*\)\([^a-zA-Z]\)\([a-zA-Z][a-zA-Z]*$\)/\4\2\3\1/' passwd
把passwd中出现的第一个数字和最后一个单词替换位置
sed 's#\([^0-9][^0-9]*\)\([0-9][0-9]*\)\([^0-9].*\)\([^a-zA-Z]\)\([a-zA-Z][a-zA-Z]*$\)#\1\5\3\4\2#' passwd
把passwd 中第一个数字移动到行末尾
sed 's#\([^0-9][^0-9]*\)\([0-9][0-9]*\)\([^0-9].*$\)#\1\3\2#' passwd
在passwd 20行到末行最前面加 ‘aaa:’
sed 's/^.*$/&aaa/' passwd