AWK: почему $ (кошка) работает на stdin, но $* не делает?

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

Но вышеупомянутый синтаксис не работает, хотя нет никакой ошибки.

Советуйте.

9
задан 2 January 2019 в 02:46

1 ответ

$(command) синтаксис возвратит вывод command. Здесь, Вы используете очень простое cat программа, чья только задание состоит в том, чтобы скопировать все со стандарта, ввела (stdin) в стандартный вывод (stdout). Так как Вы работаете awk сценарий в двойных кавычках, $(cat) расширен оболочкой перед awk скрипт запущен, таким образом, он читает echo вывод в его stdin и должным образом копирует его в свой stdout. Это затем передается 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
13
ответ дан 23 November 2019 в 04:57

Другие вопросы по тегам:

Похожие вопросы: