Linux 我可以使用“sed”搜索和替换K个行引用吗?

Linux 我可以使用“sed”搜索和替换K个行引用吗?,linux,bash,sed,Linux,Bash,Sed,我正在尝试对许多文件进行搜索和替换。我首先考虑使用“sed”,但我认为我的要求可能使“sed”不合适 简言之,假设我有一个文件,其中出现了4次“关键字”。它们一行出现一次,但在4个不同的行上 问题:我是否可以使用“sed”仅替换前两个事件。如果没有,请推荐Linux中可用的其他工具。目前,我们不讨论如何使用编程语言python、ruby和java实现这一点 我遇到了如何在一行中更改K个出现次数,但如果您知道我的意思,我还没有看到如何替换K个出现次数 如果您有任何想法,请告诉我。awk可能在这里很

我正在尝试对许多文件进行搜索和替换。我首先考虑使用“sed”,但我认为我的要求可能使“sed”不合适

简言之,假设我有一个文件,其中出现了4次“关键字”。它们一行出现一次,但在4个不同的行上

问题:我是否可以使用“sed”仅替换前两个事件。如果没有,请推荐Linux中可用的其他工具。目前,我们不讨论如何使用编程语言python、ruby和java实现这一点

我遇到了如何在一行中更改K个出现次数,但如果您知道我的意思,我还没有看到如何替换K个出现次数


如果您有任何想法,请告诉我。

awk可能在这里很方便:

awk 'i<2{i+=sub(/KEYWORD/, "FOOBAR")} 1' file

awk在这里可能很方便:

awk 'i<2{i+=sub(/KEYWORD/, "FOOBAR")} 1' file

因为它也被标记为sed,这是为了好玩,也可能是为了证明sed不是这里最好的工具:您可以使用

repl=2
for (( i = 0; i < repl; ++i )); do
    sed -i '0,/KEYWORD/ s//substitution/' infile
done
也就是说,无论需要多少次替换第一个引用。缺点:这会为每个循环处理整个文件,第一行出现的case关键字中的0 address是GNU-sed扩展名


我很确定这可以完全在sed中完成,但计数并不漂亮,例如,请参阅sed手册中的bit。

因为这也带有sed标签,出于乐趣,可能是为了证明sed不是这里最好的工具:您可以使用

repl=2
for (( i = 0; i < repl; ++i )); do
    sed -i '0,/KEYWORD/ s//substitution/' infile
done
也就是说,无论需要多少次替换第一个引用。缺点:这会为每个循环处理整个文件,第一行出现的case关键字中的0 address是GNU-sed扩展名


我很确定这完全可以在sed中完成,但计数并不完美,例如,请参阅sed手册中的位。

这可能适用于GNU sed:

sed -r '/KEYWORD/{G;h;/(\n[^\n]*){3}/!s/KEYWORD/REPLACEMENT/;s/\n.*//}' file
使用-r开关使regexp更容易使用

只关注包含关键字的行

使用保留空间HS作为变量,计算遇到关键字的次数。将保留空间追加到模式空间PS,从而为追加的每一行\n引入换行符。换行符的独特之处在于,在正常处理中,它是通过sed从模式空间中删除的。附加HS后,用当前PS替换HS,为下一次替换做好准备。如果PS中的行数少于3行,则用替换项替换关键字。删除附加的行并继续正常处理

注意:数字3 N+1可以更改为所需的任何数字,也可以通过删除替换的否定!反之亦然,即替换前遇到的关键字数

一个更通用的解决方案:

sed -r '/KEYWORD/{G;h;/^[^\n]*(\n[^\n]*){1,2}$/s/KEYWORD/REPLACEMENT/;s/\n.*//}' file

这可能适用于GNU sed:

sed -r '/KEYWORD/{G;h;/(\n[^\n]*){3}/!s/KEYWORD/REPLACEMENT/;s/\n.*//}' file
使用-r开关使regexp更容易使用

只关注包含关键字的行

使用保留空间HS作为变量,计算遇到关键字的次数。将保留空间追加到模式空间PS,从而为追加的每一行\n引入换行符。换行符的独特之处在于,在正常处理中,它是通过sed从模式空间中删除的。附加HS后,用当前PS替换HS,为下一次替换做好准备。如果PS中的行数少于3行,则用替换项替换关键字。删除附加的行并继续正常处理

注意:数字3 N+1可以更改为所需的任何数字,也可以通过删除替换的否定!反之亦然,即替换前遇到的关键字数

一个更通用的解决方案:

sed -r '/KEYWORD/{G;h;/^[^\n]*(\n[^\n]*){1,2}$/s/KEYWORD/REPLACEMENT/;s/\n.*//}' file

当然,一个选项是在模式空间中追加行,直到关键字出现k次,然后执行s并退出。这不适合k,也不是很整洁。我想,但我不是100%确定你是对的,这不适合sed。除非对文件进行了排序,否则如果发现第三次出现,基本上需要回溯任意数量的行,而sed并不是专门为其设计的。是否总是两次出现,或者您想要一个通用的K事件解决方案吗?我已经实现了一些周围的bash脚本,以给出给定文件中K应该是什么。所以为了回答你的问题,我确实需要一个通用的解决方案,但我可能已经有了。我只需要处理这个划分的替换K线的情况。仅供参考,我正在调查“awk”。谢谢。一个选项当然是在模式空间中添加行,直到关键字出现k次,然后执行s并退出。这不适合k,也不是很整洁。我想,但我不是100%确定你是对的,这不适合sed。除非对文件进行了排序,否则如果发现第三个匹配项,基本上需要回溯任意数量的行,而sed不需要
ally为。它总是两次出现,还是您想要一个针对K次出现的通用解决方案?我已经实现了一些周围的bash脚本,来告诉我给定文件中的K应该是什么。所以为了回答你的问题,我确实需要一个通用的解决方案,但我可能已经有了。我只需要处理这个划分的替换K线的情况。仅供参考,我正在调查“awk”。谢谢。在我尝试这个之前,我必须先了解一下“awk”。我现在就去做。很快回来。谢谢。这不仅有效,而且我认为这是解决这个问题的最佳方案。非常感谢,阿努巴瓦!在我尝试这个之前,我必须先了解一下“awk”。我现在就去做。很快回来。谢谢。这不仅有效,而且我认为这是解决这个问题的最佳方案。非常感谢,阿努巴瓦!