2017-02-06 1 views
0

Моя текущая оболочка является Баш, ноBash -c AWK дает другой результат

echo '1 2 3 4'| awk '{print $2}' 

и

bash -c " echo '1 2 3 4'| awk '{print $2}' " 

дает другой результат. Os - это Linux. Что не так во втором высказывании?

+0

@ hek2mgl Я чувствую, что ответы на вопрос, который вы связывали, поскольку дублировать недостаточно, чтобы ответить на проблему OP. – Aaron

+0

Что заставляет вас думать об этом? – hek2mgl

+0

@ hek2mgl Принятый ответ другого вопроса подскажет использовать одиночные кавычки для сохранения литералов, но это нелегко адаптируется к команде 'bash -c' из-за двойного расширения и трудности записи одиночных кавычек в тексте, который заключен в одинарные кавычки. – Aaron

ответ

2

В вашей второй команде $2 оценивается, прежде чем передал awk, что дает следующую команду:

echo "1 2 3 4" | awk "{print }" 

Чтобы избежать этого, вы можете использовать этот ужасный синтаксис:

bash -c 'echo "1 2 3 4"| awk '"'"'{print $2}'"'"'' 

Or этот синтаксис предложен chepner:

bash -c $'echo "1 2 3 4" | awk \'{print $2}\'' 

Проблема заключается в том, что расширение переменной выполняется здесь дважды: первый раз, когда вычисляется команда bash -c, а второй раз, когда порожденный процесс bash оценивает свою командную строку.

Мой первоначальный ответ состоял в том, чтобы сменить команду на bash -c 'echo "1 2 3 4"| awk "{ print $2 }'", что действительно позволило избежать расширения в текущей оболочке. Однако, в породившей bash процесса, расширение было выполнено на следующей команды:

echo "1 2 3 4" | awk "{print $2 }" 

И $2 был расширен в пустую строку.

Поэтому нам нужна эта команда, которая будет выполнен в породившей bash:

echo "1 2 3 4" | awk '{print $2 }' 

И мы должны окружить его одинарные кавычки в текущей оболочке:

bash -c 'echo "1 2 3 4" | awk '{print $2 }'' 

За исключением здесь awk цитаты закройте кавычки параметра bash -c, что приводит к приведенной выше команде, где мы используем '"'"', чтобы написать одну цитату внутри текста с одним текстом.

+0

Я уже думал об этом и пытался, но тот же результат –

+0

@RovshanMusayev жаль, что вы правы, я должен был проверить свою команду. Я удалю этот ответ, пока я проверю, что случилось. – Aaron

+0

@RovshanMusayev Я нашел команду, которая работает, но я уверен, что это можно сделать более элегантно. Я отредактирую, если найду его, или вам может подождать еще один ответ. – Aaron

3

Как насчет использования ЗДЕСЬ-документа?

bash <<'EOH' 
echo '1 2 3 4'| awk '{print $2}' 
EOH 

Обратите внимание, что я уронил опцию -c оглушить, и одиночные кавычки вокруг EOH необходимы, чтобы избежать оценки $ 2 на уровне оболочки.

+0

Да, это тоже работает, спасибо большое! –

+0

Больше, чем мое решение. Мне любопытно, что вы имеете в виду с EOH, хотя (любая строка может использоваться, и нормой является использование EOF для «End Of File»). Edit: nvm, 'End Of Heredoc', я полагаю. – Aaron

+0

Это решение отличается от другого решения. Это решение передает команды для bash над 'stdin'. Другое решение (и вопрос) передает их в качестве аргументов командной строки для bash. – anishsane

 Смежные вопросы

  • Нет связанных вопросов^_^