Я пытаюсь использовать awk для печати уникальных строк, возвращаемых командой. Для простоты предположим, что это команда ls -alh
.
Если я запускаю следующую команду в своей оболочке Z, awk
показывает все строки, напечатанные ls -alh
ls -alh | awk '!seen[$0]++'
Однако, если я запускаю ту же команду с $SHELL -c
, экранируя ! с обратной косой чертой я вижу только первую строку вывода.
$SHELL -c "ls -alh | awk '\!seen[$0]++'"
Как я могу убедиться, что последняя команда выводит те же результаты, что и первая?
РЕДАКТИРОВАТЬ 1:
Я сначала подумал ! может быть проблема. Но изменение выражения '!seen[$0]++'
на 'seen[$0]++==0'
имеет ту же проблему.
Обновлено еще раз:
Похоже, я тоже должен был избежать $. Поскольку я не знаю причины этого, я не буду публиковать ответ.
Это сумасшествие в любом случае. $SHELL
может быть, например. /bin/csh
или /bin/fish
, синтаксис которых полностью отличается от оболочки Bourne. Просто запустите sh
, если вы это имеете в виду.
Мой $SHELL
это zsh. Мне просто любопытно, почему эту команду нужно запускать по-разному при вызове с $SHELL
и без, даже если оба являются zsh.
Во второй форме $0
рассматривается как переменная оболочки в строке с двойными кавычками. Замена создает интересно искаженную команду awk
:
> print $SHELL -c "ls -alh | awk '\!seen[$0]++'"
/bin/zsh -c ls -alh | awk '!seen[-zsh]++'
Переменная не подставляется в первой форме, так как находится в одинарных кавычках.
В этом ответе обсуждается, как строки с одинарными и двойными кавычками обрабатываются в bash
и zsh
:
Разница между одинарными и двойными кавычками в Bash
Экранирование $
, чтобы $0
передавалось в awk
, должно работать, но обратите внимание, что цитирование в командах, которые анализируются несколько раз, может оказаться очень сложным.
> print $SHELL -c "ls -alh | awk '\!seen[\$0]++'"
/bin/zsh -c ls -alh | awk '!seen[$0]++'
какой вывод из
echo "${SHELL}"
?