最近在学习《Linux命令行和shell脚本编程大全》(第四版)这本书,对于自己遇到的问题以及通过搜索引擎和书籍中的解决方案进行一个案例的剖析,希望对于像我这样的初学者,有一个帮助。
next命令有两种模式:第一种是单行模式,使用小写的 n
来识别;第二种是多行模式,使用大写的N
来识别。
1 单行模式**n
**
告诉sed命令流转到下一行,而不需要返回命令的第一行,实际上,如果按照sed正常的命令的顺序的情况下,会执行完当前行中的所有命令,然后再流转到下一行。**word is qurresome,show me the code
** :
题设:
删除首行后的第一个空行,其余空行不进行删除
代码语言:shell复制 [root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# cat data5.txt
first line.
third line.
end of line.
如果你直接使用d
删除,那么会将所有空行均删除,除非你进行了寻址处理,如下:
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# sed '/^$/d' data5.txt
first line.
third line.
end of line.
而使用n
命令,即可避免这种情况:
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# sed '/first/{n;d}' data5.txt
first line.
third line.
end of line.
2 多行模式**N
**
告诉sed命令,将下一行附加到模式空间,并且返回命令的第一行,这样sed编辑器可以多模式空间内的数据进行合并处理,同样**word is qurresome,show me the code
**:
题设:
如果要在数据文件中查找一个可能会分散在两行中的文本短语,那么这是一个很管用的方法。这里有个例子:
代码语言:shell复制 [root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# cat data1.txt
On Tuesday, the Linux System
Admin group meeting will be held System
Admin should attend.
All System Admins should attend.
Thank you for your cooperation.
可以看到案例中有三处System Admin
,两处为换行,一处有在一行中,如果仅仅使用简单的替换,如下:
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# sed 's/System Admin/Linux System/g' data1.txt
On Tuesday, the Linux System
Admin group meeting will be held System
Admin should attend.
All Linux Systems should attend.
Thank you for your cooperation.
可以发现,仅是对处于同一行的内容进行了替换,对于换行的没有效果,此时多行模式N
就有用武之地了:
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# sed 'N;s/SystemnAdmin/LinuxnSystem/g' data1.txt
On Tuesday, the Linux Linux
System group meeting will be held System
Admin should attend.
All System Admins should attend.
Thank you for your cooperation.
3 关于多行模式的图解
眼尖的朋友能看到我在上述例子中特意加了一个g
的全局替换的参数,但是结果,依然未能实现在多行模式中对相邻的两行的换行的System Admin
完成替换。个人理解内部逻辑应该是这样的,如下:
第零步是初始化的状态:我们可以看到打印区域是空的,模式空间也是空的
第一步从数据流中取第一条数据,放在模式空间
由于命令的第一步是多行模式,因此仍然需要从数据流中取下一条数据,附加到模式空间,进入第二步:
此时多行命令可以对模式空间的两行数据进行合并处理,进行替换操作,进入第三步:
数据处理好以后进行打印操作,进而进入下一步,将数据从模式空间清除,扔入”垃圾桶“
我们可以看到第二行其实还有一个System
,但是这一行数据已经移除模式空间,并且不会再进入数据流了,因此此处的System
便不再会被sed命令所替换了。继续往下:
继续取下一行数据放入模式空间,下一步:
将模式空间的两行数据进行合并处理进行脚本替换操作,进入下一步:
没有匹配成功,但是依然进行打印出来,进入下一步:
第8步将数据从模式空间移除到”垃圾箱“,进入下一步:
取数据流中的下一条数据到模式空间,进入下一步,需要再从数据流取下一条数据附加到模式空间数据后:
发现执行多行模式命令的时候,发现没有下一行数据了,脚本执行,打印,并移出模式空间到”垃圾桶“
4 关于多行模式的思考
当仅仅有多行模式,并且在没有分支的情况下,如果对于连续行的相同跨行字符是无法一次性被处理掉的,除非可以通过其他类似于分支的手段进行迂回处理。这一点希望初学者可以明白其中的道理。