sed理论讲解、实战
1.Sed是操作、过滤和转换文本内容的强大工具,常用功能有增删改查、过滤、取行.
options(常用参数):
-n:使用安静(silent)模式,在一般 sed 的用法中,所有来自 STDIN 的数据都会被输出到终端上. 但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行才会被列出来. -e:直接在命令列模式上进行 sed 的动作编辑; -r:sed 的动作支持的是延伸型正规表示法的语法.(默认是基础正规表示法语法) -i:直接修改读取的文件内容,而不是输出到终端.
function(功能):
a:新增,a的后面可以接字串,这些字串会append到目标行的下一行; d:删除,因为是删除,所以 d 后面不接任何东西; i:插入,i的后面可以接字串,这些字串会在insert到目标行的上一行; p:列印,即:将某个选择的数据打印.通常p会与-n搭配使用; s:取代,可以直接进行取代,一般搭配正则使用.
2.a 追加文本到指定行后;i 插入文本到指定行前
cat person.txt 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO # 单行插入 sed '2a 106,dandan,CSO' person.txt sed '2i 106,dandan,CSO' person.txt # 多行插入 sed '2a 106,dandan,CSO\n107,bingbing,CCO' person.txt sed -ir '13i Port 52113\nPermitRootLogin no\nPermitEmptyPasswords no' /root/hehe.sshd
3.d 删除指定的行
sed '2d' person.txt # 对第n行操作 sed '2,5d' person.txt # 对n到m行操作,包括第n,m行 sed '3,$d' person.txt # 对n到最后一行($代表最后一行)操作,包括第n行 sed '/zhangyao/d' person.txt # 对匹配zhangyao的行操作 sed '/oldboy/,/Alex/d' person.txt # 对匹配oldboy的行到匹配Alex的行操作 # 对匹配oldboy的行到第10行操作,如果前10行没有匹配到oldboy,则显示10行以后的匹配oldboy的行,如果有的话. sed '/oldboy/,10d' person.txt # 打印文件内容但不包含oldboy,其实就是删除包含"oldboy"的行 sed '/oldboy/d' person.txt
4.p 输出指定内容,默认会输出两次匹配的结果,因此使用n取消默认输出
sed '2p' person.txt # 会取出所有内容 sed -n '2,3p' person.txt # 会取出想要的内容 sed -n '1~2p' person.txt # 取出奇数行 sed -n '2~2p' person.txt # 取出偶数行 sed -n 'p' person.txt # 取出所有行 # 按字符串查询 sed -n '/CTO/p' person.txt sed -n '/CTO/,/CFO/p' person.txt # 混合查询 sed -n '/CTO/,/CFO/p' person.txt # 前两行没有匹配到feixue,就向后匹配,如果匹配到feixue就打印此行 sed -n '/feixue/,2p' person.txt
5.分组替换--sed的后向引用
sed -n 's#()()#\1\2#gp' file # 前两个##之间对匹配到的内容进行处理,可以分组,也可以不分,取决于想做什么操作 cat a.txt I am oldboy linux teacher sed -n 's#^.*m ##gp' a.txt oldboy linux teacher sed -nr 's#^.*m (.*) l.*$#\1#gp' a.txt oldboy # sed调换元素位置 # /etc/passwd文件第一行是:root:x:0:0:root:/root:/bin/bash sed -nr '1s#(^.*):x.*$#\1#gp' /etc/passwd # 取出root sed -nr '1s#(^.*):.*$#\1#gp' /etc/passwd # 取出root:x:0:0:root:/root # 是因为贪婪模式(能多取就多取) # 将第一行内容分成三组: sed -nr '1s#(^.*)(:x.*:)(/.*$)#\2#gp' /etc/passwd 输出第二部分是:x:0:0:root:/root:,它为什么不输出:x:0:0:root:, 把/root:/bin/bash给第三部分呢?还是因为贪婪模式. [:alnum:]--匹配任意一个字母或数字字符 # 示例:[[:alnum:]]+ [:alpha:]--匹配任意一个字母字符 # 示例:[[:alpha:]]{4} # 想把第一行的第一个元素和最后一个元素对调,就得把这一行内容分成三组: sed -nr '1s#([[:alnum:]]+)(:.*:)(/.*$)#\1#gp' /etc/passwd sed -nr '1s#([[:alpha:]]+)(:.*:)(/.*$)#\1#gp' /etc/passwd sed -nr '1s#([[:alpha:]]{4})(:.*:)(/.*$)#\1#gp' /etc/passwd # 匹配非冒号的字符,至少一个 sed -nr '1s#([^:]+)(:.*:)(/.*$)#\1\3#gp' /etc/passwd
6.特殊符号及命令
a.{}相当于乘法分配律 sed -n '2,4p;=' person.txt # 打印2-4行,并显示所有行的行号 sed -n '2,4{p;=}' person.txt # 打印2-4行,只显示2-4行的行号 b.打印不可见字符(如制表符、换行符等)之l sed -n 'l' person.txt c.转换之y tr 'abc' 'ABC' person.txt # 这两种方式都是一一对应转换的 sed 'y#abc#ABC#' person.txt d.退出之q(查看几行内容,然后退出,只能指定单个数字,不能指定范围) sed '3q' person.txt e.读入之r(在指定行之后添加内容,默认是每一行都添加) sed 'r a.txt' person.txt sed '1r a.txt' person.txt # 合并两个文件内容 sed '$r a.txt' person.txt
7.模式空间(保持空间先不深究)
# n:清空当前模式空间,然后读入下一行; sed -n 'n;p' person.txt 102,zhangyao,CTO 104,yy,CFO 跟打印偶数行有点类似,但原理不同,读入第一行,遇到n,然后被清空;读入第二行,遇到p,然后打印. # N:不清空当前模式空间,然后读入下一行; cat test.txt first line second line third line sed "=" test.txt | sed 'N;s#\n# #' 1 first line 2 second line 3 third line # 经过第一步处理,此时的模式空间为: 1$ first line$ 2$ second line$ 3$ third line$ 第一行遇到N,换行符被转换为空格,读入下一行,但不做处理.
以后处理文件内容,想把奇数行和偶数行关联起来,可以用模式空间来做.
8.模拟其他命令
cat person.txt sed -n 'p' person.txt sed ' ' person.txt grep "zhang" person.txt sed -n '/zhang/p' person.txt grep -v "zhang" person.txt sed -n '/zhang/ !p' person.txt # 打印前两行的四种方法 head -2 person.txt sed -n '1,2p' person.txt sed '3,$d' person.txt sed '2q' person.txt wc -l person.txt sed -n '$=' person.txt
老男孩教育三剑客之sed行天下:https://blog.oldboyedu.com/commands-sed/