模式重复时如何删除两个模式之间的线(删除包括模式)

Posted

技术标签:

【中文标题】模式重复时如何删除两个模式之间的线(删除包括模式)【英文标题】:How to delete lines between two patterns(deleting inclusive of patterns) when pattern repeats 【发布时间】:2021-10-15 18:26:19 【问题描述】:

我有一个包含重复模式的文件。只有当有重复的模式时,我才想删除这些模式之间的所有行。

例如,如果输入文件是:

Pattern1=File1
cat
dog
PatternEnd1
blah
blah
Pattern1=File1
fish
dog
Pattern1End
blah
blah
Pattern1=File1
tiger
dog
Pattern1End

输出应该是:

Pattern1=File1
cat
dog
PatternEnd1
blah
blah
blah
blah

我尝试使用 sed 并执行 sed '/Pattern1=File1/,/PatternEnd1/d' 但只要模式匹配,它就会删除所有内容。我想删除重复模式之间的所有内容,同时保留第一次出现。

我想在 Perl 脚本中执行此操作。

【问题讨论】:

你喜欢perl时为什么要标记sedawk 【参考方案1】:

有几种方法可以做到这一点。我会使用保留空间:

sed -n '/Pattern1=File1/x;/^$/!p;d;;/Pattern1End/n;h;d;;H'

如果您遇到Pattern1=File1,请打印保留空间中的任何内容(如果有的话)并继续。如果您遇到Pattern1End,请抓住下一行并将其存储在保留空间中,覆盖那里的内容。否则,请收集您在暂存空间中阅读的任何内容。

【讨论】:

嗨,抱歉,我拼错了结束模式。 Pattern1=File1..PatternEnd1 是重复模式。只有第一次出现的应该被保留,重复出现的应该被删除。谢谢。【参考方案2】:

在 Perl 中,您可以使用 flip-flop operator。例如:

perl -lne 'if (/^Pattern1=File1$/ .. /^Pattern1End$/)  
              print if !$flag  else $flag=1; print' file

【讨论】:

感谢您的意见。但是,此代码正在删除所有重复项,我想保留其中一个并删除所有重复的谢谢 我使用您提供的输入对其进行了测试(在将 PatternEnd1 更改为 Pattern1End 之后,因为我认为这是一个错字(?))并且它没有删除第一个.. 什么输入文件你用过吗? 我还测试了我提供的示例文件,它工作正常,但不确定为什么它不适用于我拥有的原始文件。下面 awk 实用程序提供的解决方案对我有用。非常感谢您的帮助,非常感谢。【参考方案3】:
awk '/^Pattern1=File1$/ f=f2;f1=1 !f; /^Pattern1End$/ f2=f1;f=0' file

这个方法的意思是f直到顺序找到开始和结束模式后才能设置。 (“模式”是正则表达式吗?考虑How do I find the text that matches a pattern?)

【讨论】:

谢谢@rowboat,awk 实用程序为我创造了奇迹。但是,当我在循环中运行时,只有当我输入它正在工作的唯一文件名时,它才会给我正确的结果(很多重复项)。作为一种解决方法,对于来自循环的每个新比较,我将输出重定向到临时文件。有什么办法可以将它作为 awk 循环运行以摆脱重定向到临时文件的麻烦。提前谢谢你。 谢谢我找到了循环运行它的方法,但是如果你能解释一下逻辑,那将是非常可观的。我对 awk 完全陌生。【参考方案4】:

这可能对你有用(GNU sed):

sed '/Pattern1=File1/:a;N;/Pattern1End/!ba;x;/./x;d;x;h' file

收集Pattern1=File1Pattern1End 之间的行。

检查保留空间以查看是否设置了标志,如果设置了则删除集合。

否则,设置标志并打印集合。

替代方案:

sed '/Pattern1=File1/,/Pattern1End/x;/Pattern1End/x;d;x;h' file

【讨论】:

以上是关于模式重复时如何删除两个模式之间的线(删除包括模式)的主要内容,如果未能解决你的问题,请参考以下文章

如何删除或替换两个模式之间的多行文本

删除图案上方的线

如何在两种模式之间打印行,包括或排他(在sed,AWK或Perl中)?

在 UITableView 编辑模式下更改删除按钮标题 [重复]

猫鼬 |如何从此猫鼬模式中删除重复错误[重复]

如何从bash中的多个文件名中删除公共前缀模式[重复]