曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 3466|回复: 0
打印 上一主题 下一主题

在 sed 中匹配换行小结

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2013-3-16 18:28:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在《
G 与 h 命令》 中已经举出了相关的例子,在这里再进行一个小结。

像如下的这种形式,不会匹配到换行符(\n) :
sed 's/\n//g'         
sed 's/groad\n// '            
sed 's/groad\ngoogle/groad/               

为什么上述语句达不到处理换行的目的?这得看 sed 是如何读入输入内容的。

sed  是个基于行处理的工具,它每次仅读入一行,除非你对它另有安排。这样一来,在任何时候,pattern space (可参考:《
pattern space 和 hold space 的概念》)里也总是只有一行内容。这也就是说,对于读入 pattern space 的这一行内容,sed 会自动将其后的换行符移除;当处理相关的匹配后并打印出来时,sed 又会给它再加上换行符。因此需要注意的关键是:当该行在 pattern space 里时,它末尾是没有换行符的。


明白了上面这一点,也就容易理解 sed 不能像上述几种方式那样处理换行符了。比如说 sed 's/groad\ngoogle/groad/  这句,sed 会分成两次分别读入 groad 和 google 这两行内容,其间根本不会遇到换行符,因此更谈不上一下子匹配 groad\ngoogle 这种情况,所以替换工作就不能被执行。

那么如何处理换行符呢?实际上 sed 已经给出了几个相关的命令:N, P, D 。

N :从输入再读入一行,然后将其追加到 pattern space 中,这样一来 pattern space 中就有了两行内容(假设之前只有一行内容),并且这两行中间会有一个换行。

P :将 pattern space 中的内容打印出来,直到第 1 个换行处(若没有新行,那就全部打印出来)。

D:删除 pattern space 里面的内容,直到第 1 个换行处(若没有新行,则全部删除);并且开启一个新的命令处理循环,也就是说,在 D 命令后面的所有语句不会被执行,而跳到命令组的开始处执行。

下面是用这几个命令来处理的一些实例:

例一:
$ echo -e "welcome\nto\nwww\ngroad\nnet" | sed ':begin;$!N;s/\n//;tbegin;'welcometowwwgroadnet
删除掉所有的换行符,但保留最后一个。

例二:
$ echo -e "welcome\nto\nwww\ngroad\nnet" | sed ':begin;$!N;s/\(w.w\)\n/\1/;tbegin;P;D'
welcome
to
wwwgroad
net
上面使用了标签 begin 。$!N 表示如果还没到最后一行($!),则再读入一行并放到 pattern space 中(N)。然后使用 s/\(w.w\)\n/\1/; 判断匹配,若是匹配,那么就去掉换行符(使用 \1 取代);当替换成功时,一个 t 命令又跳回到 begin 标签处执行;若是没发生替换,那么不会执行 t 跳转,而是接着往下执行 P 和 D 命令。连续执行 P 和 D 命令,也就是相当于打印 pattern space 中的 1 行然后将其清出 pattern space 。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-16 00:42 , Processed in 0.060124 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表