AWK:如何在 gensub() 函数的正则表达式字段中有反向引用 \1?
AWK: how to have backreference \1 in gensub() function's regex field?
我有以下模式:
$ echo -e "1>1>659,659>659>660\n1>1>683,683>683>684\n1>1>712,712>712>713\n1>1>1080648,1>1>1080660\n1>1>1081100,1>1>1081114"
1>1>659,659>659>660
1>1>683,683>683>684
1>1>712,712>712>713
1>1>1080648,1>1>1080660
1>1>1081100,1>1>1081114
我想替换在逗号和大于号 (>) 之间连续出现相同数字的模式。所以,为了识别 grep 我会这样做:
$ echo -e "1>1>659,659>659>660\n1>1>683,683>683>684\n1>1>712,712>712>713\n1>1>1080648,1>1>1080660\n1>1>1081100,1>1>1081114" |
grep -Eo "([0-9]+),>"
659,659>659
683,683>683
712,712>712
这是对同一组的两个反向引用。
我知道在 awk 中使用 gensub() 我可以在替换字段中有反向引用。但是我怎么能在正则表达式字段中拥有它呢?像这样:
result = gensub(/([0-9]+),\1>\1/,"my replaced string", "g", string)
我怎样才能做到这一点?
这里有一个 sed
的解决方案。
sed 's|\([0-9]\+\),>|Replaced string|g'
echo -e "1>1>659,659>659>660\n1>1>683,683>683>684\n1>1>712,712>712>713\n1>1>1080648,1>1>1080660\n1>1>1081100,1>1>1081114" | sed 's|\([0-9]\+\),>|Replaced string|g'
1>1>Replaced string>660
1>1>Replaced string>684
1>1>Replaced string>713
1>1>1080648,1>1>1080660
1>1>1081100,1>1>1081114
希望你能接受 sed
而不是 awk
但是如果 awk
是强制性的,这里是一个笨拙的 awk
脚本。
awk -F "[>,]" '{sub(","">","Replaced string")}1'
echo -e "1>1>659,659>659>660\n1>1>683,683>683>684\n1>1>712,712>712>713\n1>1>1080648,1>1>1080660\n1>1>1081100,1>1>1081114" | awk -F "[>,]" '{sub(","">","Replaced string")}1'
1>1>Replaced string>660
1>1>Replaced string>684
1>1>Replaced string>713
1>1>1080648,1>1>1080660
1>1>1081100,1>1>1081114
如果您想验证第三个字段始终为数字。
添加以下条件:
awk -F "[>,]" ' ~ "^[0-9]+$"{sub(","">","Replaced string")}1'
Awk 不支持正则表达式中的反向引用,因为这样做需要比 awk 使用的正则表达式引擎慢得多的正则表达式引擎(请参阅 https://swtch.com/~rsc/regexp/regexp1.html),这不是必需的,也很少需要。这可能是你想要做的,使用 GNU awk 作为第三个参数来匹配():
$ awk 'match([=10=],/([0-9]+),/,a){ sub(a[1]","a[1]">"a[1],"my replaced string") } 1' file
1>1>my replaced string>660
1>1>my replaced string>684
1>1>my replaced string>713
1>1>1080648,1>1>1080660
1>1>1081100,1>1>1081114
或使用任何 awk:
$ awk 'match([=11=],/([0-9]+),/){ a=substr([=11=],RSTART,RLENGTH-1); sub(a","a">"a,"my replaced string") } 1' file
1>1>my replaced string>660
1>1>my replaced string>684
1>1>my replaced string>713
1>1>1080648,1>1>1080660
1>1>1081100,1>1>1081114
我有以下模式:
$ echo -e "1>1>659,659>659>660\n1>1>683,683>683>684\n1>1>712,712>712>713\n1>1>1080648,1>1>1080660\n1>1>1081100,1>1>1081114"
1>1>659,659>659>660
1>1>683,683>683>684
1>1>712,712>712>713
1>1>1080648,1>1>1080660
1>1>1081100,1>1>1081114
我想替换在逗号和大于号 (>) 之间连续出现相同数字的模式。所以,为了识别 grep 我会这样做:
$ echo -e "1>1>659,659>659>660\n1>1>683,683>683>684\n1>1>712,712>712>713\n1>1>1080648,1>1>1080660\n1>1>1081100,1>1>1081114" |
grep -Eo "([0-9]+),>"
659,659>659
683,683>683
712,712>712
这是对同一组的两个反向引用。
我知道在 awk 中使用 gensub() 我可以在替换字段中有反向引用。但是我怎么能在正则表达式字段中拥有它呢?像这样:
result = gensub(/([0-9]+),\1>\1/,"my replaced string", "g", string)
我怎样才能做到这一点?
这里有一个 sed
的解决方案。
sed 's|\([0-9]\+\),>|Replaced string|g'
echo -e "1>1>659,659>659>660\n1>1>683,683>683>684\n1>1>712,712>712>713\n1>1>1080648,1>1>1080660\n1>1>1081100,1>1>1081114" | sed 's|\([0-9]\+\),>|Replaced string|g'
1>1>Replaced string>660
1>1>Replaced string>684
1>1>Replaced string>713
1>1>1080648,1>1>1080660
1>1>1081100,1>1>1081114
希望你能接受 sed
而不是 awk
但是如果 awk
是强制性的,这里是一个笨拙的 awk
脚本。
awk -F "[>,]" '{sub(","">","Replaced string")}1'
echo -e "1>1>659,659>659>660\n1>1>683,683>683>684\n1>1>712,712>712>713\n1>1>1080648,1>1>1080660\n1>1>1081100,1>1>1081114" | awk -F "[>,]" '{sub(","">","Replaced string")}1'
1>1>Replaced string>660
1>1>Replaced string>684
1>1>Replaced string>713
1>1>1080648,1>1>1080660
1>1>1081100,1>1>1081114
如果您想验证第三个字段始终为数字。 添加以下条件:
awk -F "[>,]" ' ~ "^[0-9]+$"{sub(","">","Replaced string")}1'
Awk 不支持正则表达式中的反向引用,因为这样做需要比 awk 使用的正则表达式引擎慢得多的正则表达式引擎(请参阅 https://swtch.com/~rsc/regexp/regexp1.html),这不是必需的,也很少需要。这可能是你想要做的,使用 GNU awk 作为第三个参数来匹配():
$ awk 'match([=10=],/([0-9]+),/,a){ sub(a[1]","a[1]">"a[1],"my replaced string") } 1' file
1>1>my replaced string>660
1>1>my replaced string>684
1>1>my replaced string>713
1>1>1080648,1>1>1080660
1>1>1081100,1>1>1081114
或使用任何 awk:
$ awk 'match([=11=],/([0-9]+),/){ a=substr([=11=],RSTART,RLENGTH-1); sub(a","a">"a,"my replaced string") } 1' file
1>1>my replaced string>660
1>1>my replaced string>684
1>1>my replaced string>713
1>1>1080648,1>1>1080660
1>1>1081100,1>1>1081114