【问题标题】:sed - behaviour of holdspacesed - 保持空间的行为
【发布时间】:2012-04-05 04:04:48
【问题描述】:

我有(来自 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)

【问题讨论】:

    标签: regex sed pattern-matching


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 感谢您的快速澄清,三人组。我确实误解了“d”的含义。所以要恢复(如果我错了,请纠正我),脚本将行放在保持空间中,直到它碰到一个空行或文件的末尾,然后继续搜索段落(如果它碰到段落)。它会重新开始,直到到达最后一行。
    • 没错。尽管您提供的脚本需要 AAA 和 BBB 和 CCC 存在(不是或)。
    猜你喜欢
    • 1970-01-01
    • 2013-10-09
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多