使用SED删除单个重复模式之间的所有线条



我想使用sed删除在整个文本文件中重复的模式之间的所有线条。

输入

SET ENG_1
blah blah
blah blah
SET ENG_2
blah blah
blah blah
SET TEST
blah blah
blah blah
SET ENG_5
blah blah
blah blah
SET OPEN
blah blah
blah blah
SET ENG_10
blah blah
blah blah

有多个SET ENG_#行,但我永远不知道最后的数字是多少。我想删除SET ENG_和以SET开头的下一行之间的所有行。

所需的输出

SET ENG_1
SET ENG_2
SET TEST
blah blah
blah blah
SET ENG_5
SET OPEN
blah blah
blah blah
SET ENG_10

我想编辑到适当的文件,例如在sed中使用-i选项。

我的尝试

这是我尝试过的:

sed -i "/SET ENG_/,/SET ENG_/{//!d}" $MYFILE

它仅在第一次发生时起作用,因此我得到此输出:

SET ENG_1
SET ENG_2
blah, blah
blah blah

如何更改我的方法以获取所需的输出?

这可能对您有用(gnu sed):

sed -r '/SET/!b;:a;$!{N;ba};s/((SET)[^n]*n).*n([^n]*2)/13/' file

这将保留第一个和最后的模式(在您的情况下SET)。

此替代方案也将删除第一个和最后的模式:

sed -r '/SET/!b;:a;$!{N;ba};s/[^n]*(SET).*1[^n]*n?//' file

在阅读对您的修正案时,也许这可能对您有用:

sed -ni ':a;/^SET ENG_[1-9]/{p;:b;$q;n;/^SET/ba;bb};p' file

如果您有一些类似的文字:

cat file
start text
SET ENG_1
blah blah
blah blah
SET ENG_2
blah blah
blah blah
SET ENG_3
blah blah
blah blah
SET ENG_4
end text
blah blah
blah blah

这将在第一次SET ENG之前和上次SET ENG之前打印所有数据:

awk '/SET ENG/ {e=NR;if (!f) f=NR} {a[NR]=$0} END {for (i=1;i<=NR;i++) if (f>i||i>e) print a[i]}' file
start text
end text
blah blah
blah blah

使用awk与自定义记录分离器您可以使用:

awk -v RS= '{sub(/SET ENG.*SET ENG[^n]*n/, "")} 1' file
start text
end text
blah blah
blah blah

此示例使用与Jotne答案中的示例数据。

它从您的问题中看起来就是您所需要的:

$ grep 'SET ENG_' file
SET ENG_1
SET ENG_2

如果这不是您想要的,请编辑您的问题以阐明您的要求,提供更真实的代表性输入和预期输出。

基于您的新所需输出,我会解释您要做的事情:

  • 如果/SET ENG/匹配,请关闭输出
  • 如果/SET [anything else]/将其重新切换为
  • 打印所有SET

此脚本这样做:

$ awk '/SET/ { if (/ENG/) { print; f = 0 } else f = 1 } f' file
SET ENG_1
SET ENG_2
SET TEST
blah blah
blah blah
SET ENG_5
SET OPEN
blah blah
blah blah
SET ENG_10

相关内容

  • 没有找到相关文章

最新更新