我的文件包含未知数量的文本块,其中包含起始关键字“Start”、结束关键字“End”以及它们之间的可选文本,每一行上都有一个确切的关键字“Disk”,我需要删除其中存在的文本块它们之间没有任何关系,请参阅示例。
我正在处理这样的输入:
Server1:Start
Server1:End
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End
,我想要的输出是这样的:
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End
我知道,我可以使用“awk”或“sed”来查找两行之间的文本,但如果这两行多次出现或者这两行之间没有文本,我不知道该怎么办。
我运行的是 Ubuntu 17.10。
期待任何帮助。
编辑:我第一次删除了该帖子,因为我认为我可以使用 来完成此操作sed -e '/Start/,/End/d'
,但这实际上删除了所有内容。
答案1
要删除连续行Start
和End
行,应该在 GNU sed 中执行以下操作:
$ sed -e '/Start/ {N; /^\(.*\):Start\n\1:End$/d }' < input
如果我们看到Start
,则加载下一行N
,然后查看缓冲区的内容是否在两行上都相同(Somename:Start\nSomename:End
是换行符)。如果有,请将其删除。这里,是对 中第一个组的引用,并且与在那里遇到的相同字符串匹配。只表示任意数量 ( ) 的任意字符 ( )。Somename
\n
\1
\(..\)
.*
*
.
使用sed -e '/Start/,/End/d'
确实会删除每一行,因为范围匹配开始和结束模式之间的所有行。输入中的所有内容都在Start
和之间End
,因此所有内容都会被删除。
答案2
另一个解决方案,因为我喜欢尝试在 awk 中执行这些操作。
BEGIN {
RS="End\n"
ORS="End\n"
}
NF > 2
使用内置RS
或记录分隔符变量,awk 会将每个之间视为End\n
一条记录,并假设 和servername:Start
都是servername:End
单个单词,这只是通过该行打印具有两个以上字段的行的情况NF > 2
。如果这是 true,则将打印整行,并End\n
用作输出记录分隔符 ( ORS
)
~$>echo '
Server1:Start
Server1:End
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End
' | awk 'BEGIN { RS="End\n"; ORS="End\n"; } NF > 2;'
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End