首页 > 解决方案 > $0 中的 awk gsub 也会更改变量

问题描述

我正在尝试将进入 awk 的文本分配给一个变量,然后更改 $0 ,然后输出原始字符串和更改后的字符串:

# echo "This is a test" |awk '{text=$0; gsub(/ /,"%20"); print $text; print $0;}' 
This%20is%20a%20test
This%20is%20a%20test

但我期待它会回来

This%20is%20a%20test
This is a test

尝试更改 #text 变量会做同样的事情。

# echo "This is a test" |awk '{text=$0; $text gsub(/ /,"%20"); print $text; print $0;}' 
This%20is%20a%20test
This%20is%20a%20test

运行 DSM 6.2 的 Synology 上的 GNU Awk 4.1.3,API:1.1(GNU MPFR 3.1.3,GNU MP 6.0.0)

标签: variablesawkgsub

解决方案


让我们分析您的原始代码行:

awk '{text=$0; gsub(/ /,"%20"); print $text; print $0;}'
  • text=$0:非常简单,您将当前记录存储在变量中text
  • gsub(/ /,"%20"):这将替换%20字符串中的所有空格$0。这是根据POSIX 标准

    gsub(ere, repl[, in]) 表现得像sub,除了它应该替换参数ere$0in参数中所有出现的正则表达式,当指定时。

    应该理解,这种替换是就地的。因此$0现在已更新且不同于text.

  • print $text: 这是罪魁祸首,你想做print text却写了$textPOSIX 标准规定:

    字段变量应由 a 指定,$后跟数字或数值表达式。

    正如您所写$text并且text当前是一个字符串,它会尝试将字符串转换为预期的数字。当它失败时,转换返回ZERO,此时 this$text等同于$0表示当前记录(您之前使用 更新gsub)。

  • print $0: 在这里打印当前记录。

综上所述:

如果您期望以下输出:

This%20is%20a%20test
This is a test

以下两awk行给出了这个:

awk '{text=$0; gsub(/ /,"%20",text); print text; print $0)'
awk '{text=$0; gsub(/ /,"%20"); print $0; print text }'

推荐阅读