AWK:为什么$(cat)可用于stdin,但$ *不起作用?


9
echo '((3+(2^3)) * 34^2 / 9)-75.89' | awk "BEGIN{ print $(cat) }"

上面的语法在计算结果为“ 1337”时工作良好。

echo '((3+(2^3)) * 34^2 / 9)-75.89' | awk "BEGIN{ print $* }"

但是上述语法不起作用,尽管没有错误。

请给我建议。

Answers:


13

$(command)语法将返回的输出command。在这里,您使用的是非常简单的cat程序,其唯一的工作就是将所有内容从标准输入(stdin)复制到标准输出(stdout)。由于您是awk在双引号中运行脚本,因此在脚本运行之前$(cat)外壳会将其展开,因此它将输出读入其stdin并将其适当地复制到其stdout。然后将其传递到脚本。您可以通过以下方式查看此操作:awkechoawkset -x

$ set -x
$ echo '((3+(2^3)) * 34^2 / 9)-75.89' | awk "BEGIN{ print $(cat) }"
+ echo '((3+(2^3)) * 34^2 / 9)-75.89'
++ cat
+ awk 'BEGIN{ print ((3+(2^3)) * 34^2 / 9)-75.89 }'
1337

因此,awk实际上正在运行BEGIN{ print ((3+(2^3)) * 34^2 / 9)-75.89 }',返回1337。

现在,$*是一个特殊的shell变量,它可以扩展到给shell脚本提供的所有位置参数(请参阅参考资料man bash):

   *      Expands to the positional parameters, starting from one.  When the expan
          sion  is not within double quotes, each positional parameter expands to a
          separate word.  In contexts where it is performed, those words  are  sub
          ject  to  further word splitting and pathname expansion.  When the expan
          sion occurs within double quotes, it expands to a single  word  with  the
          value  of each parameter separated by the first character of the IFS spe
          cial variable.  That is, "$*" is equivalent to "$1c$2c...",  where  c  is
          the  first  character of the value of the IFS variable.  If IFS is unset,
          the parameters are separated by spaces.  If IFS is null,  the  parameters
          are joined without intervening separators.

但是,此变量在此处为空。因此,awk脚本变为:

$ echo '((3+(2^3)) * 34^2 / 9)-75.89' | awk "BEGIN{ print $* }"
+ awk 'BEGIN{ print  }'
+ echo '((3+(2^3)) * 34^2 / 9)-75.89'

$*扩展为空字符串,并且awk被告知要打印一个空字符串,这就是为什么你没有输出。


您可能只想使用bc

$ echo '((3+(2^3)) * 34^2 / 9)-75.89' | bc
1336.11

应该使用bc -l,否则您会得到上面发布的差异(除法的结果已被截断)。
cmbuckley

@cmbuckley我试图通过与它玩耍来打印1337 scale=(我假设OP希望与leetspeak一起玩),但我找不到办法。在我的系统上bc -l返回1336.99888888888888888888
terdon
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.