在awk中解释错误的Shell变量

3
在以下代码中,我试图将shell变量传递给awk。但是当我尝试以a.sh foo_bar的形式运行它时,打印输出为“未声明foo”,而当我以a.sh bar_bar的形式运行它时,打印输出为“已声明foo”。awk存在错误吗?还是我在这里做错了什么?
我正在使用gawk-3.0.3版本。
#!/bin/awk

model=$1

awk ' {

      match("'$model'", /foo/)
      ismodel=substr("'$model'", RSTART, RLENGTH)
      if (  ismodel != foo ) {
        print  " foo is not declared"
      } else {
        print  " foo is declared"
      }
     }
    ' dummy

dummy是一个只有单个空白行的文件。

谢谢。

3个回答

2
你应该使用AWK的变量传递,而不是复杂引用:
awk -v awkvar=$shellvar 'BEGIN {print awkvar}'

你的脚本是一个shell脚本,但你有一个AWK shebang行。你可以将它改为#!/bin/sh


我在这里粘贴代码时犯了一个错误(#!/bin/awk的问题)。如果我使用-v选项传递变量,问题可能会得到解决。但问题仍然是为什么awk检查比较的方向相反?如果-v是传递shell变量的唯一选项,那么awk不应该总是打印“foo未声明”。对吗? - Anil Rana

1

这不是一个bug,而是你的代码中的错误。有问题的行是:

if (  ismodel != foo ) {

这里foo应该是"foo"。现在你正在与一个空变量进行比较。当你有匹配时,它会返回false,没有匹配时则返回true。所以问题不在于你使用shell变量的方式。

但正如其他回答者所说,传递参数给awk的首选方法是使用-v开关。这也适用于当你决定将awk脚本放在单独的文件中时,并且可以避免所有引号问题。

我也不确定你使用虚拟文件的方式。这只是为了举例吗?否则,你应该省略文件并将所有代码放在BEGIN {}块中。


谢谢Schot!就像你说的那样,它起作用了。这里的虚拟数据只是为了举例说明。 - Anil Rana

0

使用 -v 选项从 shell 中传递变量

awk -v model="$1" '{
  match(model, /foo/)
   .....
}
' dummy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接