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命令中,该命令将删除第二行并输出文件的其余部分,但我无法弄清楚这一点.
这是使用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 :a在s///成功时跳转到标签.
另一种方法是使用uniq命令coreutils,这不是那么灵活,但在这种情况下效果很好:
uniq -w5 infile
Run Code Online (Sandbox Code Playgroud)
Perl解决方案:
perl -ne 'print unless $t and /^TITLE/; $t = /^TITLE/'
Run Code Online (Sandbox Code Playgroud)
它记住$t变量中的前一行是否为TITLE 。