【sed】进阶
2024-09-05 08:04:28
sed的基本用法已能满足大多数需求,但当需要时,知道这些高级特效的存在及如何使用将提供莫大的帮助!
1. 多行命令
sed编辑器提供三个用于处理多行文本的特殊命令:
- N:将数据流的下一行加入当前模式空间
- D:删除多行组中的一行
- P:打印多行组中的一行
【next命令】
单行next命令:
小写的n命令,将下一行文本移入模式空间(工作空间)并挤走已有文本,即跳过当前行进入下一行。
# cat data1.txt
this is the header line this is the data line this is the last line
经n命令处理后可跳过第一行:
# sed '/header/{n;d}' data1.txt
this is the header line
this is the data line this is the last line
多行next命令:
大写的N命令,将下一行文本并入当前模式空间,即加到已有文本之后。两个文本行合并成一行,仍以换行符分隔。
# cat data2.txt
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
经N命令处理后:
# sed '/first/{N;s/\n/ /}' data2.txt
This is the header line.
This is the first data line. This is the second data line.
This is the last line.
Tips:使用N命令可查找分散在两行的文本。注意最后一行进入模式空间,执行N命令由于没有后续的可读入行,会导致后面的命令无法执行。
【多行删除命令】
单行删除命令d和N命令一起使用时,会将模式空间的文本全部删除;
多行删除命令D,只删除模式空间的第一行,即删除到换行符为止的所有字符(包含换行符)。
# cat data5.txt This is the header line.
This is a data line. This is the last line.
# sed '/^$/{N ; /header/D}' data5.txt
This is the header line.
This is a data line. This is the last line.
Tips:这种办法可实现删除特殊行,比如需要同时满足两种条件的行。
【多行打印命令】
单行打印命令会打印出模式空间内的所有文本;
多行打印命令仅打印多行模式空间的第一行,即打印换行符之前的所有字符。
# sed -n '/header/{N;P}' data5.txt
This is the header line.
2. 保持空间
sed编辑器除了模式空间(patten space)外,还有一个保持空间(hold space)。处理模式空间的某些行时,可以使用保持空间临时保存一些行。
命令
|
描述
|
h
H
g
G
x
|
将模式空间复制到保持空间
将模式空间附加到保持空间
将保持空间复制到模式空间
将保持空间附加到模式空间
交换模式空间和保持空间
|
读懂以下命令,理解保持空间用法:
# sed -n '/first/ {h ; p ; n ; p ; g ; p }' data2.txt
This is the first data line.
This is the second data line.
This is the first data line.
3. 排除命令
感叹号命令(!)用于排除某个命令,即让原本的命令不起作用。
# sed -n '/header/p' data2.txt
This is the header line.
普通p命令打印匹配文本行,使用!后,效果相反,不打印该行而打印其它行:
# sed -n '/header/!p' data2.txt
This is the first data line.
This is the second data line.
This is the last line.
结合保持空间反转文本行的顺序:
# sed -n '{1!G ; h ; $p }' data2.txt
This is the last line.
This is the second data line.
This is the first data line.
This is the header line.
Tips:sed编辑器默认会将命令循环应用在每一行文本上,因此合理使用命令,可写出简洁高效的sed脚本
4. 改变流
sed编辑器提供了改变脚本执行流程的方法。
【分支】
分支(branch)命令(b)可只对数据流中的特定行执行命令。
格式:
[address]b [label]
address参数定义触发分支的行数,label参数用于定义要跳转的位置。若没有加label,则会跳过脚本。
加address,不加label,跳过后面所有脚本:
# sed '{2,3b ; s/This is/Is this/ ; s/line./test?/}' data2.txt
Is this the header test?
This is the first data line.
This is the second data line.
Is this the last test?
加address,加label,分支匹配处的行跳到标签处,执行标签后的命令;不匹配的行执行所有命令:
# sed '/first/b jump1 ; s/This is the/No jump on/; :jump1 ; s/This is the/Jump here on/' data2.txt
No jump on header line.
Jump here on first data line.
No jump on second data line.
No jump on last line.
不加address,b命令无条件跳转到标签上,可造成循环的效果:
# echo "This, is, a, test, to, remove, commas." | sed -n '{:start;s/,//1p;b start}'
This is, a, test, to, remove, commas.
This is a, test, to, remove, commas.
This is a test, to, remove, commas.
This is a test to, remove, commas.
This is a test to remove, commas.
This is a test to remove commas.
^C
该脚本不会停止循环,可使用/,/b start代替b start,在没有逗号时自动结束循环。
【测试】
测试(test)命令(t)会根据替换(s)命令的结果来跳转到某个标签。
不加label,跳过后面所有命令:
# sed 's/first/matched/; t ; s/This/Here/' data2.txt
Here is the header line.
This is the matched data line.
Here is the second data line.
Here is the last line.
加label,跳转到label处:
# echo "This,is,a,test,to,remove,commas." | sed -n '{:start ; s/,/ /p ; t start}'
This is,a,test,to,remove,commas.
This is a,test,to,remove,commas.
This is a test,to,remove,commas.
This is a test to,remove,commas.
This is a test to remove,commas.
This is a test to remove commas.
# sed 's/first/matched/; t ;s/This/Here/;s/line/LINE/' data2.txt
Here is the header LINE.
This is the matched data line.
Here is the second data LINE.
Here is the last LINE.
# sed 's/first/matched/; t jump ;s/This/Here/; :jump ;s/line/LINE/' data2.txt
Here is the header LINE.
This is the matched data LINE.
Here is the second data LINE.
Here is the last LINE.
Tips:使用标签和t命令可在脚本命令中形成循环
5. 模式替代
【&符号】
&符号可以提取命令中匹配模式中的全部文本。
# echo "The cat sleeps in his hat." | sed 's/.at/"&"/g'
The "cat" sleeps in his "hat".
【替代单独的单词】
用圆括号来定义子模式,在替换模式中用\1等引用子模式,可提取匹配模式中的部分文本。
# echo | sed ':start;s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;t start'
,,
Tips:圆括号必须转义
6. 重定向sed输出
【 $() 】
默认情况,sed会将脚本结果输出到STDOUT,可使用$()将输出保持到变量中。和变量替换一样
最新文章
- codeforces 724D(贪心)
- [Android进阶]学习AccessibilityService实现微信抢红包插件
- JDK6的switch支持不是很好
- 基于MapReduce的关系代数运算(1)
- EBS报表输出文件格式控制
- C#利用Lambda和Expression实现数据的动态绑定
- Android-MVVM架构-Data Binding的使用
- excel导入、导出
- vsCode工具做react开发,几个常用插件
- Autotools setting
- nunit2.5.7 单元测试时提示:“当前不会命中断点 还没有为该文档加载任何符号”
- uva10603-倒水问题-暴力枚举-隐式图搜索
- longing加载中实例
- .Net Core连接RabbitMQ集群
- Mac OSX 安装qemu
- WKWebView 里 JS 和 native 通信的例子
- 使用swagger实现web api在线接口文档(转载)
- gstreamer应用笔记
- Nginx Open File Cache
- Python爬虫教程-26-Selenium + PhantomJS