如何删除以相同单词开头的第二行连续行?

Roe*_*gel 10 regex bash perl awk sed

我有一个文本文件,其中包含以'TITLE'和'DATA'开头的交换行,但有时会出现以'TITLE'开头的重复行:

TITLE something
DATA some data
TITLE something else
DATA其他数据
TITLE更多
TITLE额外信息
DATA更多数据

我希望能够检测以'TITLE'开头的重复行,并且只保留每对这样的第一行.
我发现用于捕获这些的正则表达式^TITLE.*\n^TITLE.*\n现在我想将它合并到一个单行perl/ bash/ sed/ awk命令中,该命令将删除第二行并输出文件的其余部分,但我无法弄清楚这一点.

Tho*_*hor 6

这是使用GNU sed执行此操作的一种方法:

sed -r 'N; /(TITLE)[^\n]*\n\1/ s/\n.*//; P; D' infile
Run Code Online (Sandbox Code Playgroud)
  • N 将第二行放入模式空间.
  • 匹配测试两行是否以TITLE.
  • 如果是这样,第二行被删除.
  • P; D 打印并删除模式空间中的第一行.

输出:

TITLE something
DATA some data
TITLE something else
DATA some other data
TITLE some more
DATA some more data
Run Code Online (Sandbox Code Playgroud)

编辑 - 处理任意数量的重复

正如Nikina Reklawyks在评论中指出的那样,上述解决方案仅适用于两个连续的行TITLE,为了处理任意数量的重复,可以添加一个简单的循环,如下所示:

sed -r ':a; N; /(TITLE)[^\n]*\n\1/ s/\n.*//; ta; P; D' infile
Run Code Online (Sandbox Code Playgroud)

ta语句使sed :as///成功时跳转到标签.

另一种方法是使用uniq命令coreutils,这不是那么灵活,但在这种情况下效果很好:

uniq -w5 infile 
Run Code Online (Sandbox Code Playgroud)


cho*_*oba 5

Perl解决方案:

perl -ne 'print unless $t and /^TITLE/; $t = /^TITLE/'
Run Code Online (Sandbox Code Playgroud)

它记住$t变量中的前一行是否为TITLE 。