进阶sed
1 多行命令
N:将数据流中的下一行加进来创建一个多行组来处理
D:删除多行组中的一行
P:打印多行组中的一行
next命令
删掉两个空行
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# cat data3 header line data line last line [root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed '/^$/d' data3 header line data line last line
如果需要删除第一个空行,但是没有任何能够标识空行的文本。解决办法是用n命令,查找到header行,n命令会让sed编辑器移动到文本的下一行,也就是空行
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed '/header/{n;d}' data3 header line data line last line
合并文本行
多行版本的next命令(用大写的N)会将下一行添加到模式空间中已有的文本后
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# cat data4 header line first data line second data line last line [root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed '/first/{N;s/\n/ /}' data4 header line first data line second data line last line
查找分散在两行中的文本短语,N比较实用,这边用通配符(.)来匹配空格或者换行符
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed 'N;s/system administrator/desktop user/' data5 on tuesday,the linux system administrator's group meeting well be held all system administrator show attend. [root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed 'N;s/system.administrator/desktop user/' data5 on tuesday,the linux desktop user's group meeting well be held all system administrator show attend. [root@iZbp11f8g5h7oozejqy6k6Z test5.9]# cat data5 on tuesday,the linux system administrator's group meeting well be held all system administrator show attend.
但是仍有小问题,这个脚本总是在执行sed编辑命令前将下一行文本读入到模式空间,当它执行到最后一行的时候,就没有下一行可堵了,所以N命令会
叫sed编辑器停止,由于system administrator出现在了最后一行,可以这么解决:
将单行命令放到N命令前面,多行命令放到N命令后面
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed 's/system administrator/desktop user/;N;s/system.administrator/desktop\n user/' data5 on tuesday,the linux desktop user's group meeting well be held all desktop user show attend.
多行删除命令
d单行删除
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed 'N;/system\nadministrator/d' data5 all system administrator show attend.
D多行删除
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed 'N;/system\nadministrator/D' data5 administrator's group meeting well be held all system administrator show attend.
删除数据流中出现在第一行前的空白行
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed '/^$/{N ; /header/D}' data3 header line data line last line [root@iZbp11f8g5h7oozejqy6k6Z test5.9]# cat data3 header line data line last line
多行打印命令
-n阻止脚本输出,p和P大同小异,P只打印多行模式空间的第一行
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed -n 'N; /system\nadministrator/p' data5 on tuesday,the linux system administrator's group meeting well be held [root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed -n 'N; /system\nadministrator/P' data5 on tuesday,the linux system
保持空间
h 将模式空间复制到保持空间
H 将模式空间附加到保持空间
g 将保持空间复制到模式空间
G 将保持空间附加到模式空间
x 交换模式空间和保持空间内容
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# cat data4 header line first data line second data line last line [root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed -n '/first/{h;p;n;p;g;p}' data4 first data line second data line first data line
分析以上代码
1、sed脚本在地址中用正则表达式过滤出含有first的行
2、当含有first的行出现时,h将该行放入保持空间
3、p命令打印模式空间的内容,第一个数据行内容
4、n命令提取数据流下一行,并放到模式空间
5、p打印模式空间内容,现在是第二个数据行
6、g将保持空间的内容放回到模式空间,替换当前内容
7、p打印模式空间的内容
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# cat data4 header line first data line second data line last line [root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed -n '{1!G;h;$p}' data4 last line second data line first data line header line
分支
分支(branch)命令b格式如下,允许支队数据流中的特定行执行一组命令
[address]b [label]
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed '{2,3b ; s/line/lines/}' data4 header lines first data line second data line last lines
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed '{ 2,3b ;s/this is/is this/ ; s/data line/date lines/}' data4 is this header date lines this is first data line this is second data line is this last date lines
分支命令可以定义一个要跳转到的标签,标签以冒号开始,最多可以是7个字符长度
:label2
要指定标签,加到b命令后面即可,使用标签允许跳过地址匹配出的命令,但仍然执行脚本中其他命令
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# cat data4 this is header line this is first data line this is second data line this is last line [root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed '{/first/b app1 ; s/this is/no jump on/ ;:app1 ;s/this is/jump here on/}' data4 no jump on header line jump here on first data line no jump on second data line no jump on last line
跳转命令指定如果文本行中出现了first,程序应该跳到标签为app1的脚本行。如果分支命令的模式没有匹配,sed编辑器会继续执行脚本命令,包括分支标签后的命令,
因此,所有的替换命令都会在不匹配分支模式的行上执行
如果某行匹配了分支模式,sed编辑器就会跳到带有分支标签的那行,因此,只有最后一个替换命令会执行。
这个例子演示了跳转到sed脚本后面的标签上。也可以跳转到脚本中靠前的标签上,这样就达到了循环的效果
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo "this, is, a, test, do, remove, commas."|sed -n '{ :start s/,//p /,/b start }' this is, a, test, do, remove, commas. this is a, test, do, remove, commas. this is a test, do, remove, commas. this is a test do, remove, commas. this is a test do remove, commas. this is a test do remove commas.
脚本每次迭代都会删除第一个逗号,并打印字符串。只会在行中有逗号的时候进行跳转,最后一个逗号被删除后,分支命令不再会执行。
测试
测试命令使用与分支命令相同的格式
[adress]t [label]
跟分支命令一样,在没有指定标签的情况下,如果测试成功,sed会跳到脚本的结尾
测试命令提供了对数据流中文本执行基本的if-then语句的一个低成本办法。
举个例子,如果已经做了一个替换,不需要做另一个替换,就可以用测试命令
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed '{s/first/matched/ ;t ;s/this is/no match/}' data4 no match header data line this is matched data line no match second data line no match last data line
第一个命令会查找模式文本first,如果匹配了行中模式,就会替换文本,而测试命令会跳过后面的替换命令来替换该行,去替换其他行中匹配的行。如果未匹配,则后面的替换命令会将该行也替换
有了测试命令,就能结束之前用分支命令形成循环
:start s/,//p t start }' this is, a, test, do, remove, commas. this is a, test, do, remove, commas. this is a test, do, remove, commas. this is a test do, remove, commas. this is a test do remove, commas. this is a test do remove commas.
模式替换
&符号
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo "the cat sleeps in the hat" | sed 's/.at/"&"/g' the "cat" sleeps in the "hat"
&符号会提取匹配替换命令中指定模式的整个字符串,如何提取部分:
sed编辑器用圆括号来定义替换模式中的子模式,可以在替代模式中使用特殊字符来引用每个子模式。替代字符由反斜线和数字组成。数字表明子模式的位置。
sed编辑器会给第一个子模式分配字符\1,给第二个字模式分配字符\2,以此类推
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo "the system administrator manual"|sed 's/\(system\) administrator/\1 user/' the system user manual
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo "that furry cat is pretty"|sed 's/furry \(.cat\)/\1/' that furry cat is pretty
在大数字中插入逗号
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo "1234567"|sed '{:start ;s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;t start}' 1,234,567
将匹配模式分为
.*[0-9]
[0-9]{3}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~