1

我有(来自 sed 网站http://sed.sourceforge.net/sed1line.txt)这个单行:

sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'

其目的是在段落中搜索 AAA、BBB 或 CCC。

我对剧本的理解:

  • '/./' 匹配不为空的每一行
  • '{}' 括号内的所有命令都处理匹配的行
  • 'H' 用匹配的行附加保持空间
  • '$!d' 从模式空间中删除除最后一行之外的所有内容
  • 'x' 交换模式和保持空间
  • '/AAA/!d' 搜索 AAA 段落并打印

我不清楚的是:

  1. 在holdspace中应该有几个单独的行(对于每个段落),为什么我能够搜索整个段落?保持空间中的行是否合并为一行?
  2. sed 如何知道一个段落何时结束,而另一个段落何时开始在保持空间中?
  3. 为什么我必须附加'$!d',为什么'$ d'不够?为什么在这种情况下我不能省略 '-n' 并使用 '$p' 而不是 '$!d'?

非常感谢您的每一条评论!

我的测试数据(匹配每个段落中的 XX):

YYaaaa
aaa1
aaa2
aXX3
aaa4

YYbbbb
bbb1
bbb2

YYcccc
ccc1
ccc2
ccc3
cXX4
ccc5

YYdddd
ddd1
dXX2

使用以下命令:

sed -ne '/./{H;$!d};x;/XX/p' test2

版本:

$ sed --version
GNU sed-Version 4.2.1
$ bash --version
GNU bash, Version 4.2.10(1)-release (x86_64-pc-linux-gnu)
4

1 回答 1

1

它将一个段落作为单独的行收集到保留空间 ( H) 中,然后当您点击一个空行时,/./它会失败并且它会落入x基本上会破坏下一段的保留空间的段落。

为了正确处理最后一段,它需要处理一个没有空行的段落,因此它从最后一行开始就好像它后面跟着一个空行一样。对于通过特定模式收集某些内容的脚本来说,这是一个常见的习惯用法(或者,换句话说,此类脚本无法处理文件末尾最后收集的数据是一个常见错误)。

换句话说,如果我们正在查看一个非空行,请将其添加到保留空间,除非它是文件中的最后一行,否则将其删除并从脚本的开头重新开始,并使用下一个输入行。(也许你的理解d不完整?这是什么$!d意思。)

否则,我们有一个空行或文件结尾,并且保留空间包含零行或多行文本(一个段落,可能为空)。将它们交换到模式空间(当前空行方便地移动到保持空间)并检查模式空间。如果它无法匹配我们的表达式之一,请将其删除。否则,默认操作是打印整个模式空间。

于 2012-04-04T19:45:15.300 回答