【问题标题】:Using shell variables in gensub in Awk在 Awk 的 gensub 中使用 shell 变量
【发布时间】:2017-01-15 07:30:40
【问题描述】:

我试图回答这里提出的问题

How do I sed only matched grep line

如下

 awk -F":" -v M="Mary Jane" -v A="Runs" -v S="Sleeps" '{OFS=":" ; print gensub(/(M):(A)/,"\\1;S","g")}'

但它不起作用所以我猜 gensub 无法识别传递给 awk 的 shell 变量 M、A 和 S,有没有办法在 awk 的 gensub 中使用 shell 变量?

【问题讨论】:

    标签: awk sed


    【解决方案1】:

    您遇到的不是因为您使用的是gensub(),而是与正则表达式有关。有正则表达式文字,例如$0~/foo/,然后是动态正则表达式,它们是在评估时转换为正则表达式的字符串,例如$0~"foo"{var="foo"} $0~var。如果您想在 ANY 正则表达式上下文中使用变量,那么您需要一个动态正则表达式,因此这是您需要使用的语法,而不是正则表达式文字语法。见https://www.gnu.org/software/gawk/manual/gawk.html#Computed-Regexps

    你所写的正确语法是:

    awk -F":" -v M="Mary Jane" -v A="Runs" -v S="Sleeps" '{OFS=":" ; print gensub("("M"):"A,"\\1;"S,"g")}'
    

    但这有一些语义问题(例如,部分匹配和为每一行设置 OFS 而不是一次,当它甚至从未使用过时,几乎可以肯定不必要地使用 "g" 而不是 1 以及为什么在你使用正则表达式时使用真的想对字符串进行完全匹配)

    【讨论】:

    • 感谢 ED,根据您的解释,我将命令修改为 awk -F":" -v M="Mary Jane" -v A="Runs" -v S="Sleeps" ' BEGIIN{OFS=":"}{ print gensub("("M"):"A,"\\1:"S,1)}' 我有一个问题,在 gensub 中你为什么在搜索中保留 A双引号外的模式和引号外的替换模式中的 S ?它们不应该用双引号括起来,但是当我这样做时,我没有得到想要的结果。请指教
    • 双引号分隔文字字符串。变量不会在文字字符串中扩展,因为它们是文字。如果你写A="x"; print A,你会得到变量A的值,即"x",但是如果你写A="x"; print "A",你会得到文字字符串"A"的值,当然,@987654334 @。在动态正则表达式的上下文中使用字符串和变量也不例外。 $0 ~ "foo"A 匹配字符串"foox",由"foo" 与变量A 的内容串联产生的字符串,而$0 ~ "fooA" 匹配字符串"fooA"
    • 但是你在 gensub("("M"):"A,"\\1:"S,1)} 里面有双引号 M 是如何在那里扩展的?
    • 非常感谢 Ed 的详细解释。
    • 艾德,你有鹰眼!
    猜你喜欢
    • 2014-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    相关资源
    最近更新 更多