Есть ли способ повторить черный слэш, за которым следует перевод строки в bash?

570
InFlames

Я пытаюсь завершить строку с \чем-то другим Сначала я сделал это, но он просто печатает \ n:

$ echo -e "Test\\\nNewline"  Test\nNewline 

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

$ echo -e "Test\\ \nNewline" Test\  Newline 

Как я могу это сделать, чтобы после \?

ОБНОВЛЕНИЕ: Теперь нет проблем, так как я вижу, что добавление еще двух слешей дает желаемый результат. Но мне все еще интересно, почему это так?

$ echo -e "Test\\\\\nNewline" Test\ Newline 
3
Я не знаю, но что-то смешное в двойных кавычках. Попробуйте это `$ echo -e 'tt \\\ nP'` barlop 8 лет назад 0
так что возьмите свой первый пример, который, по вашему мнению, должен работать, а что нет, попробуйте изменить двойные кавычки на одинарные. barlop 8 лет назад 0

2 ответа на вопрос

2
Steven

Bash Reference Manual: Double Quotes: Within double quotes, backslashes that are followed by one of these characters [including backslash] are removed.

Therefore, "Test\\\\\nNewline" is replaced with Test\\nNewline before being passed as a parameter to the echo command.

To demonstrate this:

$ echo -e "Test\\\\\nNewline" Test\ Newline $ echo -e 'Test\\\nNewline' Test\ Newline 
нет сомнений в том, что ответ находится в этих правилах, но не могли бы вы объяснить, как это приводит к тому, что `\\\\\ n" `требуется для выполнения обратной косой черты в новой строке? Так, например, для тех 5 обратных слешей n (что в его примере) становится тем, чем он становится. barlop 8 лет назад 0
Спасибо, это все объясняет! Вы пропустили \ в примере с одинарными кавычками. ;) InFlames 8 лет назад 0
@InFlames Исправлено. Steven 8 лет назад 0
echo без -e - это одно. Но он сделал echo -e в своем примере, так что ваша демонстрация имеет результат с большим количеством обратных косых черт, чем результат в его примере. Было бы интересно, если бы вы могли объяснить его пример. barlop 8 лет назад 0
-1 его примером было эхо-е и двойные кавычки. У твоего нет `-e` barlop 8 лет назад 0
@ Стивен, я хотел бы увидеть "как bash изменяет параметр, отправляемый в echo" на его примере, а в его примере используется `-e` barlop 8 лет назад 0
@Steven Операция echo отличается от -e и без, хотя ваше объяснение осталось прежним. Все, что вы сделали, это скопировали / вставили результат с -e, и ваше объяснение осталось прежним. И вы не указали, относится ли ваше объяснение «Поэтому« Test \\\\\ nNewline »на« Test \\ nNewline »к случаю -e или нет». Так как ваш предыдущий ответ дал случай без -e, а ваш более новый ответ дает случай с, почему бы вам не объяснить оба случая вместо того, чтобы изменить свой ответ, чтобы показать только один. т.е. не удаляйте пример из вашего ответа barlop 8 лет назад 0
@ barlop Почему бы вам не отредактировать ответ так, как считаете нужным? Steven 8 лет назад 0
Давайте [продолжим это обсуждение в чате] (http://chat.stackexchange.com/rooms/26757/discussion-between-barlop-and-steven). barlop 8 лет назад 0
Давай не будем Я доволен своим ответом как есть. Если нет, отредактируйте ответ. У вас есть репутация, чтобы сделать это. Steven 8 лет назад 0
2
Gordon Davisson

Стивен уже объяснил, почему так много обратной косой черты необходимо; Я хотел бы перечислить некоторые, возможно, лучшие способы сделать то же самое. Во-первых, использование одинарных кавычек вместо двойных кавычек пропускает дополнительный уровень интерпретации / удаления escape:

$ echo -e "Test\\\nNewline" Test\nNewline $ echo -e 'Test\\\nNewline' Test\ Newline 

Во-вторых, я рекомендую не использовать echoподобные вещи, поскольку разные его версии ведут себя совершенно по-разному: некоторые интерпретируют escape-последовательности в строке (например, \nдаже без -eопции), некоторые выводят «-e» как часть их вывода, и т.д. Вот пример использования / bin / echo вместо встроенной версии bash:

$ /bin/echo -e 'Test\\\nNewline' -e Test\\\nNewline 

... Это на OS X v10.10.4; это может отличаться в вашей ОС и / или версии. В любое время, когда вам нужно предсказуемое поведение с escape-интерпретацией и / или без финального перевода строки, я рекомендую printfвместо echo. Это немного сложнее: первый аргумент printf- это строка формата, в которой экранирование всегда интерпретируется, и это также может включать %последовательности, которые будут использоваться для добавления в оставшиеся аргументы (в которых экранированные последовательности не интерпретируются). Кроме того, printfавтоматически не добавляется перевод строки в конце, вы должны включить это явно. Вот несколько способов напечатать то, что вы хотите с printf:

$ printf 'Test\\\nNewline\n' # note explicit final newline Test\ Newline $ printf '%s\n' 'Test\' 'Newline' # Escape is interpreted in the format string, but not in the second argument Test\ Newline 
Это раздражает, хотя, хотя они назвали его printf, он сильно отличается от printf в C. Например, это работает в C `printf ("% d ", 'A');` он печатает 65. Тогда как с * nix printf, вы можете сделать $ printf '% s' 'A', но вы не можете сделать $ printf '% d' 'A' barlop 8 лет назад 0
@barlop Это не совсем разница в `printf`, это результат того, что оболочка не использует ту же систему типов, что и Си. (На самом деле, оболочка вообще не имеет большой части системы типов.) Как в C, так и в shell спецификация формата `% d` предполагает целое число, но C и bash имеют совершенно разные представления о том, что составляет целое число. В C `` A'` - это тип char, который является целочисленным типом и имеет значение 65. (`" A "`, с другой стороны, является массивом char, что является совсем другой вещью.) Bash на самом деле не имеет целочисленного типа, он просто имеет строки, но строка, состоящая из цифр, также является целым числом. Gordon Davisson 8 лет назад 0
@ barlop Теперь, сказав это, есть взломать. `Printf` Bash будет обрабатывать строку, начинающуюся с одинарных кавычек, как символ в стиле C. Поэтому `printf '% d'" 'A "` напечатает "65". Gordon Davisson 8 лет назад 0
как далеко зайдут хаки, например, как насчет хака для этого `printf ("% c ", 65);` печать A barlop 8 лет назад 0
@ barlop Это направление более странное. Вы должны использовать два вызова для `printf`: один с`% o` для преобразования в восьмеричное значение, а затем поместить его после обратной косой черты во втором обращении к нему, которое будет обрабатываться как восьмеричная последовательность символов на основе восьмеричного числа. `printf \\ $ (printf '% 03o' 65)` сделает это. См. [BashFAQ # 71: Как преобразовать символ ASCII в его десятичное (или шестнадцатеричное) значение и обратно?] (Http://mywiki.wooledge.org/BashFAQ/071) для получения дополнительных вариантов. Gordon Davisson 8 лет назад 0