Sed:每隔一个换行替换模式?

Sed:每隔一个换行替换模式?

有没有办法告诉sed每隔一次出现就替换该模式?或者至少每隔一行? (当然可以使用脚本,但我问自己是否sed可以做到)。

编辑

我发现

sed -e "s/pattern/replacement/g;n"

但它取代了第一次出现的情况,而不是第二次出现的情况。

例子

输入文件:

I have a pattern in each line
Also the second line has the pattern
Another pattern here
And -- you guess it -- a pattern

期望的输出:

I have a pattern in each line
Also the second line has the replacement
Another pattern here
And -- you guess it -- a replacement

答案1

sed 's/pattern/replacement/2'

将替换具有该模式的每一行上的第二次出现。


如果你有 GNU sed

sed '1~2N ; s/pattern/replacement/2'

从第一行开始1,它后面的行将被添加到模式空间,N然后该s命令将替换第二次出现的模式。然后sed将向下移动两行~2并重复。

答案2

https://stackoverflow.com/questions/5858200/sed-replace-every-nth-occurrence

该解决方案使用 awk 而不是 sed,但“使用正确的工具来完成工作”。可能是也可能不是可能的在 sed 中执行,但是即使是这样,它也将是很多使用 awk 或 perl 等工具更容易。

答案3

简单的解释:

在至少包含一次 PATTERN 的第一行中,您希望忽略它并按原样打印该行。在至少包含一次 PATTERN 的第二行中,您希望将 PATTERN 的第一个实例替换为 REPLACMENT。在至少包含一次 PATTERN 的第三行上,您希望按原样打印该行。在至少包含一次 PATTERN 的第四行上,您希望将 PATTERN 的第一个实例替换为 REPLACMENT。等等。与 PATTERN 不匹配的行应不加更改地打印。

这可以使用 Sed 轻松完成,如下所示:

sed -e '/PATTERN/ { :inside' -e 'n;s//REPLACEMENT/;t' -e 'b inside' -e '}'

或者,使用更少的空白和更短的标签:

sed -e '/PATTERN/{:i' -e 'n;s//REPLACEMENT/;t' -e 'b i' -e '}'

编辑:我刚刚重读了这个问题,发现了更难的解释:

将整个文档中第二次出现的 PATTERN 替换为 REPLACMENT,无论它是否与第一次出现在同一行。保持第一次和第三次出现不变。 ETC。

我相信这也可以使用 Sed 来完成,尽管它要棘手得多,而且我相信它取决于要使用的正则表达式。我会尝试解决一些问题并将其发布,但我现在会让这个答案与上面的简单版本保持一致。

答案4

一行中的一个符号模式: sed 's/(a[^a]*)a/\1c/g'

每隔一个模式(每行只能出现一个模式匹配。如果每行出现两个或多个匹配,则仅替换第二个)

echo -e "test\nreplace_me\ntest\ntest\nreplace_me\nreplace_me\nreplace_me" | \
sed '/replace_me/{:a;N;/replace_me.*replace_me/!Ta;s/replace_me/replaced/2;}'

相关内容