Подстановка команд и двойные кавычки: почему результаты разные?

Совместимость с POSIX -sed:

grep -e 'Success' -e 'Completed' your_file | sed 'N;s/Success with \([[:digit:]]\+\).*T_init = \([^[:space:]]\+\).*T_sink = \([^[:space:]]\+\).*/\2 \3 \1/;s/\.00//g'

GNU sed:(, в котором .не соответствует \nпо крайней мере в 4.2.2 на CentOS)

grep -e 'Success' -e 'Completed' your_file | sed 'N;s/Success with \([[:digit:]]\+\).*\n.*T_init = \([^[:space:]]\+\).*T_sink = \([^[:space:]]\+\).*/\2 \3 \1/;s/\.00//g'

Захватывает строки, содержащие Successи Completed, затем работает с двумя строками (более явно, чем необходимо )извлекает три интересующих вас поля и упорядочивает их в одну строку.

Это только усекает .00любые числа, оставляя в покое любой значащий дробный компонент (, включая что-то вроде 12.20, по-прежнему будет один конечный нуль ).

Предостережение, если некоторые из этих ...строк содержат CompletedилиSuccess

5
22.04.2020, 15:30
2 ответа

Вы правы, в данном случае дело в другом.

Решение все еще в той же ссылке , но второй пункт:

  • Nested quoting inside $() is far more convenient.

    [...]

    `...` requires backslashes around the internal quotes in order to be portable.

Таким образом,

echo "`echo \"test\"`"

не равно этому:

echo "$(echo \"test\")"

но это:

echo "$(echo "test")"

Вам нужно сравнить его с этим:

echo "`echo \\"test\\"`"
4
19.03.2021, 02:26

Причина, по которой замена команды обратными кавычками удаляет цитирование обусловлено тем, как оно реализовано:

  • Текст в обратных кавычках проходит через лексический синтаксический анализатор во второй раз перед окончательным выполнением.

    Это происходит потому, что результаты первого прохождения лексического синтаксического анализатора (, занимающего один уровень цитирования ), сохраняются в виде строки и снова проходят через полный синтаксический анализатор во время окончательного выполнения. Таким образом, подстановка команд на основе обратной кавычки удаляет два уровня цитирования.

  • Текст внутри $(...)остается неизменным до того, как он будет пропущен через полный синтаксический анализатор во время окончательного выполнения.

    • это реализовано в kshпутем записи входного текста как побочного эффекта синтаксического анализатора, когда он выполняет синтаксический анализ закрытия ')̈́', соответствующего $(.

    • это реализовано в boshи mkshпутем записи двоичного синтаксического дерева, выводимого синтаксическим анализатором, во время его синтаксического анализа для закрытия ')̈́', который соответствует $(, и реконструкции соответствующего эквивалентного исходного ввода. для этого двоичного дерева для окончательного выполнения.

    В результате подстановка команд на основе $(...)удаляет только один уровень кавычек (, как это происходит и при обычном выполнении команды ).

Из-за этой реализации подстановка команд на основе обратной кавычки приводит к непредвиденному поведению, особенно если шаблоны grepявляются частью такой команды. Вот почему $(...)рекомендуется использовать в пользу.

1
19.03.2021, 02:26

Теги

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