如何用awk替换一行中的第N个匹配项
How to replace Nth match in a line with awk
在 sed
中,您可以使用 /N
(solved so long ago) 替换第 N 个匹配项:
$ sed 's/you/ME/1' <<< "hello you are you" # 1 is superfluous here, though
hello ME are you
$ sed 's/you/ME/2' <<< "hello you are you"
hello you are ME
我正在尝试在 awk
中完成同样的事情,我发现的唯一肮脏的方法是遍历元素并保留一个计数器。
即使是更简单的情况,即匹配一个完整的字段,也会变得有点脏:
$ awk '{for (i=1;i<=NF;i++) if ($i=="you" && ++c==2) $i="ME"}1' <<< "hello you are you"
hello you are ME
因此,我想知道 gensub()
、gsub()
或 sub()
函数是否允许您提供此类参数以更直接的方式进行操作。浏览 GNU awk 手册中的 String functions 并没有显示帮助我找到它。
试试 gensub()
。我认为它只包含在 gawk 版本中,但它接受一个正则表达式来匹配、替换文本和位置:
awk '[=10=] = gensub(/you/, "ME", 1)' <<< "hello you are you"
产生:
hello ME are you
和
awk '[=12=] = gensub(/you/, "ME", 2)' <<< "hello you are you"
产生:
hello you are ME
在 sed
中,您可以使用 /N
(solved so long ago) 替换第 N 个匹配项:
$ sed 's/you/ME/1' <<< "hello you are you" # 1 is superfluous here, though
hello ME are you
$ sed 's/you/ME/2' <<< "hello you are you"
hello you are ME
我正在尝试在 awk
中完成同样的事情,我发现的唯一肮脏的方法是遍历元素并保留一个计数器。
即使是更简单的情况,即匹配一个完整的字段,也会变得有点脏:
$ awk '{for (i=1;i<=NF;i++) if ($i=="you" && ++c==2) $i="ME"}1' <<< "hello you are you"
hello you are ME
因此,我想知道 gensub()
、gsub()
或 sub()
函数是否允许您提供此类参数以更直接的方式进行操作。浏览 GNU awk 手册中的 String functions 并没有显示帮助我找到它。
试试 gensub()
。我认为它只包含在 gawk 版本中,但它接受一个正则表达式来匹配、替换文本和位置:
awk '[=10=] = gensub(/you/, "ME", 1)' <<< "hello you are you"
产生:
hello ME are you
和
awk '[=12=] = gensub(/you/, "ME", 2)' <<< "hello you are you"
产生:
hello you are ME