Почему нельзя читать программу AWK как heredoc - PullRequest
1 голос
/ 05 августа 2020

Почему два нижеприведенных похожих сценария имеют разное поведение?

Следующая команда:

{ echo a; echo b; } | awk $(cat <<'EOF'
    {print $0}
EOF
)

завершается ошибкой с этим сообщением об ошибке:

awk: syntax error at source line 1
 context is
         >>>  <<<
awk: illegal statement at source line 1
        missing }

Однако, если я сначала сохраню heredo c в переменной, он будет работать:

cmd=$(cat <<'EOF'
    {print $0}
EOF
)
{ echo a; echo b; } | awk "$cmd"

производит:

a
b

Я использую Ma c OS. Я могу воспроизвести, используя как zsh, так и POSIX sh.

1 Ответ

3 голосов
/ 05 августа 2020

Краткий ответ: используйте кавычки вокруг '$ (cat ...)', чтобы bash не анализировал вывод cat (программа awk), и рассматривайте его как единственный аргумент

{ echo a; echo b; } | awk "$(cat <<'EOF'
    {print $0}
EOF
)"

Длинный ответ: вывод $(cat ...) - это awk-программа '(print $ 0}'. Без кавычек bash расширит $ (cat) и выдаст:

   awk {print $0}

Принимая '{print' в качестве первого аргумента (программа) и принимая '$ 0}' в качестве второго аргумента (имя входного файла). Чтобы объединенная строка рассматривалась как один аргумент, необходимы кавычки. С кавычками расширенная команда (и подстановка команд):

   awk "{print $0}"
...