我想使用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