В терминале Ubuntu 18.04 LTS, когда я пишу эту команду:
echo -e "Hello\\\n"
Это дает в качестве вывода:
Hello\n
Но он должен печатать, как человек говорит , страница:
Hello\
То есть сначала напечатайте Hello
, затем \
, затем символ новой строки (а затем еще один символ новой строки). В чем проблема?
Посмотрите эти несколько echo -e
команд и их вывод :
man420@man420-X542UQ:~$ echo -e "HEllo\a\a\a\a\a\a\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\a\\\n"
HEllo\n
command-line
echo
yolin00
источник
источник
echo
в первую очередь: используйтеprintf
.Ответы:
Обратные слеши обрабатываются особым образом
echo -e
, но сначала они иногда обрабатываются особым образом оболочкой (что в данном случаеbash
) в соответствии с правилами цитирования оболочки .Аргумент на
echo
самом деле видит этоHello\\n
. Поскольку вы перешли-e
наecho
, он обрабатывает обратные слэши специально и\\
сводится к одному\
. Финалn
не избежал, поэтому выглядит буквально.Причина этого заключается в том, что до и отдельно от самой операции
echo
оболочка обрабатывает\
специально в некоторых контекстах, но не в других. Символы без кавычек\
всегда обрабатываются особым образом, одинарные кавычки\
никогда не обрабатываются особым образом, но обработка символов в двойных кавычках\
, как и в выполняемой вами команде, является более тонкой и сложной.Когда оболочка встречает в команде текст, заключенный в двойные кавычки, например
"Hello\\\n"
, она обрабатывается\
как escape-символ, когда она предшествует символу, который сам может иметь специальное значение внутри двойных кавычек, а не иначе .\
иногда имеет особое значение внутри""
, a,\
который непосредственно предшествует другому,\
имеет эффект цитирования этой секунды\
. Таким образом, внутри двойных кавычек, первые\\
свернуты в\
.\
символов есть третий\
символ, который не затрагивается этими первыми двумя и который предшествуетn
. Ноn
это не персонаж, который когда-либо рассматривался специально в двойных кавычках, поэтому\
прежде он не обрабатывается специально в этой ситуации. Таким образом,\n
остается\n
.Эффект в том, что в двойных кавычках
\\\n
интерпретируется как\\n
.Когда
echo -e
видит\\n
, первое\
удаляет особое значение из второго, поэтомуecho
печатает\n
буквально для этого текста.Если ваша цель - печатать
Hello
с дополнительной новой строкой, но без обратной косой черты (изначально вопрос был неоднозначным по этому поводу, плюс я думаю, что это полезный пример), тогда одним из решений является удаление a\
. Запускecho -e "Hello\\n"
выходовHello
с дополнительным переводом строки в конце.Лучшее решение - использовать одинарные кавычки и писать
echo -e 'Hello\n'
. Одиночные кавычки - самая сильная форма цитирования. Как правило,printf
вместо этого лучше использовать решениеecho
, которое в этом случае будетprintf 'Hello\n\n'
.Если ваша цель состоит в
Hello\
том, чтобы напечатать в том числе обратную косую черту с последующим дополнительным переводом строки , тогда подход с двойными кавычками возможен, но громоздок. Чтобы понять это, работайте задом наперед:echo -e
преобразует\\
в\
и\n
в новую строку, а двойные кавычки преобразует\\
в\
, так что вы можете сделать это с шестью обратными косыми чертами (echo -e "Hello\\\\\\n"
), потому что они\\n
превращаются в\n
одну, выходящую из другой обратной косой черты. Вы также можете сделать это с пятью, потому что двойные кавычки сохраняются,\n
когда\
не экранированы.Это иллюстрирует преимущество
echo -e
одинарных кавычек : просто поместите все, что вы хотите видеть внутри одинарных кавычек (echo -e 'Hello\\\n'
).printf
здесь тоже хорошо Один вариант естьprintf 'Hello\\\n\n'
. Но гдеprintf
действительно светит то, что вы можете включить дополнительные аргументы. Вы можете использоватьprintf '%s\n\n' 'Hello\'
, который вставляет второй аргумент (буквально,Hello\
потому что одинарные кавычки ничего не меняют) вместо%s
.источник