文本处理 - 获取 2 行,其间包含准确的文本

文本处理 - 获取 2 行,其间包含准确的文本

我的文件包含未知数量的文本块,其中包含起始关键字“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

要删除连续行StartEnd行,应该在 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

相关内容