本文旨在复习Sed文本处理的保持空间[Hold Space]、高级命令、循环标签等
知识储备
Sed除了有模式空间外,还有一个保持空间[Hold Space]
模式空间:所有的处理动作、加工都在此处,原材料加工厂,默认动作是打印到终端
保持空间:暂时存放某行内容,存放"行"仓库,无默认动作,通过命令可实现调度
高级命令:所谓的高级命令通常指模式空间 <---> 保持空间 行的交互,如何交换、覆盖、追加
Sed循环标签:shell脚本可以用for、while、until循环,而sed是通过调用标签名来实现循环
Sed高级命令工作原理如下图
高级命令
前提说明:无论是模式空间、保持空间,是一个大的容器,是可以容纳多行的!!只不过默认情况下我们做的操作都是“覆盖”行为的,所以表现为只有1行,明白了这个概念,再去理解下面的命令。
x | 交换模式空间与保持空间内容 |
d | 删除当前模式空间内容,并进入下一个循环 |
D | 删除多行模式空间中的首行,并进入下一个循环 |
n | 读取匹配到的下一行至模式空间 [会覆盖模式空间原有的值] |
N | 读取匹配到的下一行至模式空间 [追加到原有内容后] |
h | 复制模式空间内容,到保持空间, 覆盖 |
H | 复制模式空间内容,到保持空间, 追加 |
g | 复制保持空间内容,到模式空间, 覆盖 |
G | 复制保持空间内容,到模式空间, 追加 |
下面举几个循序渐进的例子:
实验文本1:
1 | 1 A |
例1:使用sed命令隔行打印输出偶数行,即第2行、第4行、第6行、第8行等。
实现代码:
1 | sed -n '{n;p}' sed.txt |
具体分析:
加工厂送来一批小鲜肉 1 A, 执行加工操作{n;p},首先做n操作
n操作 --> 由于肉不新鲜丢掉,采购下一批2 a,这里会把原来加工厂第一批肉丢掉[覆盖]
p操作 --> 肉质不错,卖给客户,即打印输出到终端上
例2:交换行顺序,预期字母出现先小写再大写,效果为首行2 a 下行1 A
实现代码:
1 | sed -n 'h;n;p;g;p' sed.txt |
具体分析:
实验文本2:
1 | lance |
例1:找出那些属于mage.com的用户,只显示用户名
实现代码:
1 | sed -n -e '/mage/!h' -e '/mage/{x;p}' sed.txt |
具体分析:
例2:整理用qq邮箱地址的人,打印出他们的邮箱地址,输出格式形如lance@mage.com
实现代码:
1 | sed -n -e '/qq.com/!h' -e '/qq.com/{H;x;s/\n//p}' sed.txt |
具体分析:
看到这里,你可能会对替换命令s/\n//p感到很奇怪,为何替换\n为空多行变1行输出了?
补充说明:模式空间、保持空间中的多行是这样的
循环标签
编程语言很大的特点是循环语句实现重复执行,sed中没有for、while、until语句,而是通过定义标签,调用标签来实现循环这种功能的。
一般格式为:
1 | sed -n ':标签名 范围1 命令1; /模式/b 标签名' filename |
例1:默认s///只能替换每行第一个被匹配的内容,当然如果使用g可以全局替换,这里我们使用标签来替换所有的lance为大写LANCE
1 | lance lance lance lance lance lance lance lance |
实现代码:
1 | sed -n ':again s/lance/Lance/;/lance/b again;p' lance.txt |
额外说明:标签名调用其实不仅可以使用b,准确来说有b调用 t调用 T调用