Shell正则表达式之sed
一、sed(无交互式修改)
1、sed概述
文本处理工具,读取文本内容,根据指定的条件进行处理,如删除、替换、添加等。
可在无交互的情况下实现相当复杂的文本处理操作被广泛应用于Shell脚本,以完成自动化处理任务。
sed依赖于正则表达式。
2、原理
3、sed命令格式
基础:
sed 选项 模式匹配 文件名
选项:
-e:指定要执行的命令,只有一个编辑命令时可以省略
-n:只输出处理后的行,读入时不显示
-i:直接编辑文件,而不输出结果
-f:用指定的脚本文件来处理输入的文本文件
简而言之:增删改查
二、实例
实例文件
[root@localhost ~]# vim 正则表达式练习.sh
root:x:100:100:/root
lrz:x:111:111:/lrz
adm:x:112:112:/adm
rooot:x:113:113:/rooot
1、基本输出效果
[root@localhost ~]# sed '' 正则表达式练习.sh
root:x:100:100:/root
lrz:x:111:111:/lrz
adm:x:112:112:/adm
rooot:x:113:113:/rooot
注:一定要加'',不然无法显示。
[root@localhost ~]# sed 正则表达式练习.sh
sed:-e 表达式 #1,字符 1:未知的命令:“�”
2、输出打印字符
[root@localhost ~]# sed 'p' 正则表达式练习.sh
root:x:100:100:/root
root:x:100:100:/root
lrz:x:111:111:/lrz
lrz:x:111:111:/lrz
adm:x:112:112:/adm
adm:x:112:112:/adm
rooot:x:113:113:/rooot
rooot:x:113:113:/rooot
注:因为'p'代表输出这个文件,sed会自己也输出一遍,所以显示两遍。
解决办法:加 -n
[root@localhost ~]# sed -n 'p' 正则表达式练习.sh
root:x:100:100:/root
lrz:x:111:111:/lrz
adm:x:112:112:/adm
rooot:x:113:113:/rooot
完美
3、只输出单独行内容
[root@localhost ~]# sed -n '1p' 正则表达式练习.sh
root:x:100:100:/root
注:在p前面加上数字,表示输出第几行内容
[root@localhost ~]# sed -n '3p' 正则表达式练习.sh
adm:x:112:112:/adm //第三行内容
如何输出几行内容,比如我要输出1-3行:
[root@localhost ~]# sed -n '1,3p' 正则表达式练习.sh
root:x:100:100:/root
lrz:x:111:111:/lrz
adm:x:112:112:/adm
更友好的显示:
[root@localhost ~]# cat -n 正则表达式练习.sh | sed -n '1,3p'
1 root:x:100:100:/root
2 lrz:x:111:111:/lrz
3 adm:x:112:112:/adm
输出最后一行:
[root@localhost ~]# cat -n 正则表达式练习.sh | sed -n '$p'
4 rooot:x:113:113:/rooot //利用$
注:输入第一行的时候,不要用^,因为不识别
[root@localhost ~]# cat -n 正则表达式练习.sh | sed -n '^p'
sed:-e 表达式 #1,字符 1:未知的命令:“^”
直接用1p就好了
输出某行及后几行:
[root@localhost ~]# cat -n 正则表达式练习.sh | sed -n '1,+3p'
1 root:x:100:100:/root
2 lrz:x:111:111:/lrz
3 adm:x:112:112:/adm
4 rooot:x:113:113:/rooot
[root@localhost ~]# cat -n 正则表达式练习.sh | sed -n '2,+3p'
2 lrz:x:111:111:/lrz
3 adm:x:112:112:/adm
4 rooot:x:113:113:/rooot
5 zhangsan:x:114:114:/zhangsan
注:超过的行不会报错,只是不输出
[root@localhost ~]# cat -n 正则表达式练习.sh | sed -n '1,+10p'
1 root:x:100:100:/root
2 lrz:x:111:111:/lrz
3 adm:x:112:112:/adm
4 rooot:x:113:113:/rooot
5 zhangsan:x:114:114:/zhangsan
6 lisi:x:115:115:/lisi
7 wangwu:x:116:116:/wangwu
8 shengjie:x:117:117:/shengjie
间隔行输出:
[root@localhost ~]# cat -n 正则表达式练习.sh | sed -n '1~2p'
1 root:x:100:100:/root
3 adm:x:112:112:/adm
5 zhangsan:x:114:114:/zhangsan
7 wangwu:x:116:116:/wangwu
[root@localhost ~]# cat -n 正则表达式练习.sh | sed -n '1~3p'
1 root:x:100:100:/root
4 rooot:x:113:113:/rooot
7 wangwu:x:116:116:/wangwu
只选择几行打印:
[root@localhost ~]# cat -n 正则表达式练习.sh | sed -n '1p;3p'
1 root:x:100:100:/root
3 adm:x:112:112:/adm
注:只能用;号,不能用逗号。
4、匹配行内容
查找有root的行:
[root@localhost ~]# cat -n 正则表达式练习.sh | sed -n '/root/p'
1 root:x:100:100:/root
查找以root开头的行:
[root@localhost ~]# sed -n '/^root/p' 正则表达式练习.sh
root:x:100:100:/root
root:111
查找结尾同理
打印root开头或lrz结尾的:
[root@localhost ~]# sed -n '/^root\|lrz$/p' 正则表达式练习.sh
root:x:100:100:/root
lrz:x:111:111:/lrz
root:111
注:需要转义|,不然无法显示,或者使用-r
[root@localhost ~]# sed -n -r '/^root|lrz$/p' 正则表达式练习.sh
root:x:100:100:/root
lrz:x:111:111:/lrz
root:111
或者用-e
[root@localhost ~]# sed -ne '/^root/p' -e '/lrz$/p' 正则表达式练习.sh
root:x:100:100:/root
lrz:x:111:111:/lrz
root:111
打印空行:[root@localhost ~]# sed -n '/^$/p' 正则表达式练习.sh
打印有空格的行:[root@localhost ~]# sed -n '/ /p' 正则表达式练习.sh
打印反斜杠:[root@localhost ~]# sed -n '/\\/p' 正则表达式练习.sh
root\1123
5、自定义分隔符替换
[root@localhost ~]# sed -n 's#/lrz#bbb#p' 正则表达式练习.sh
lrz:x:111:111:bbb
无视大小写:
[root@localhost ~]# cat -n 正则表达式练习.sh | sed -n 's/ROOT/XXX/gpi'
1 XXX:x:100:100:/root
9 XXX:111
10 XXX\1123g
或者
[root@localhost ~]# cat -n 正则表达式练习.sh | sed -n 's/ROOT/XXX/Ip'
改第十行:10s
开头加#:sed -n 's/^bin/#$/p' zz.txt
替换整行内容:sed -n 's/root/cxxx' zz.txt(c后面全部替换为内容,不识别其他)
6、删除内容
[root@localhost ~]# cat -n 正则表达式练习.sh | sed '6d'
1 root:x:100:100:/root
2 lrz:x:111:111:/lrz
3 adm:x:112:112:/adm
4 rooot:x:113:113:/rooot
5 zhangsan:x:114:114:/zhangsan
7 wangwu:x:116:116:/wangwu
8 shengjie:x:117:117:/shengjie
9 root:111
10 root\1123
7、插入
sed -n '2a hello' zz.txt //第二行后面插入
sed -n '2i hello' zz.txt //第二行上面插入
8、改源文件(sed -i)
9、读文件
sed -n ’r /etc/hosts‘ zz.txt
10、另存为
sed 'w /opt/bak' zz.txt