有没有办法告诉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;}'