gregory 列出的 pattern link 的另一个调整 -
sed '/^!$/N; /^!\n!$/!P; D'
这来自于基本模式
sed '$!N; /^\(!\)\n\1$/!P; D'
修改自
# delete duplicate, consecutive lines from a file (emulates "uniq").
# First line in a set of duplicate lines is kept, rest are deleted.
sed '$!N; /^\(.*\)\n\1$/!P; D'
解释
没有
向模式空间添加一个换行符,然后将下一行输入附加到模式空间。如果没有更多输入,则 sed 退出,不再处理任何命令。
和
附加 !地址规范末尾的字符(在命令字母之前)否定了匹配的意义。也就是说,如果 !字符跟在地址或地址范围之后,则只会选择与地址不匹配的行。
$ 是文件的结尾,所以$!N 表示在不是文件末尾最后一行的行上,“在模式空间中添加一个换行符,然后将下一行输入附加到模式中空间。”这使得模式空间“这一行和下一行”。
P
打印到第一个换行符之前的模式空间部分。
所以,/^\(.*\)\n\1$/!P; 意味着将第一行从开头复制到换行符并将其用作 \1 反向引用作为模式的一部分,这意味着匹配 2 个相同的连续行。当那些不匹配时(/!),打印第一行。如果它们 匹配 匹配,则不会打印。
D
如果模式空间不包含换行符,则开始一个正常的新循环,就像发出了 d 命令一样。否则,删除模式空间中的文本直到第一个换行符,然后使用生成的模式空间重新开始循环,而不读取新的输入行。
模式末尾的 D 正在从第一行移出,但将第二行留在模式空间中。
从字面上看,它是遍历文件,比较连续的行,并且仅在它们不相同时才打印它们。
稍微更简单的版本(例如,可能更容易阅读,尽管它仍在做几乎同样多的工作)
sed '$!N; /^!\n!$/!P; D'
这对球棒模式进行了硬编码,并且至少不存储和使用反向引用,尽管它仍然在所有行中移动。当我们看到一个单独的球棒时,我们可以通过仅堆叠线条来减少这项工作:
sed '/^!$/N; /^!\n!$/!P; D'
P 和 D 仍在做他们的事。 :)
所以我们回到了我在顶部发布的模式。
希望对您有所帮助。