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 $* }"

ただし、エラーは発生しませんが、上記の構文は機能しません。

Plzがアドバイスします。

回答:


13

$(command)構文は次のとおりの出力を返しますcommand。ここでは、cat標準入力(stdin)から標準出力(stdout)にすべてをコピーすることが唯一の仕事である非常に単純なプログラムを使用しています。あなたが実行しているのでawk、二重引用符内のスクリプトを$(cat)シェルによって展開される前にawk、読み込むようにスクリプトが実行されecho、そのstdoutにstdinと正式にコピーし、それに出力を。次に、これがawkスクリプトに渡されます。あなたはこれを実際に見ることができますset -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を返す実行中です。

これで、$*は特別なシェル変数になり、シェルスクリプトに指定されたすべての定位置パラメーターに展開されます(を参照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はリーツピークで遊んでいると思います)方法が見つかりませんでした。私のシステムにbc -l戻ります1336.99888888888888888888
terdon
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.