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

时间:2015-05-14 14:30:04

标签: bash unix 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

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

5 个答案:

答案 0 :(得分:1)

这可能适合你(GNU sed):

sed -r '/SET/!b;:a;$!{N;ba};s/((SET)[^\n]*\n).*\n([^\n]*\2)/\1\3/' 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

答案 1 :(得分:0)

如果你有这样的文字:

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

答案 2 :(得分:0)

将awk与自定义记录分隔符一起使用,您可以使用:

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

此示例使用与Jotne的答案中相同的样本数据。

答案 3 :(得分:0)

根据您新的所需输出,我会解释您尝试做的事情:

  • 如果/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

答案 4 :(得分:0)

从您的问题看,这就是您所需要的:

$ grep 'SET ENG_' file
SET ENG_1
SET ENG_2

如果这不是您想要的,请编辑您的问题以澄清您的要求,提供更真实的代表性输入以及给定输入的精确预期输出。