Когда я делаю
str="Hello World\n===========\n"
Я \n
тоже распечатал. Как я могу иметь переводы строки тогда?
Когда я делаю
str="Hello World\n===========\n"
Я \n
тоже распечатал. Как я могу иметь переводы строки тогда?
Ответы:
В bash
вы можете использовать синтаксис
str=$'Hello World\n===========\n'
Одинарные кавычки, $
начинающиеся с символа a, - это новый синтаксис, который позволяет вставлять escape-последовательности в строки.
Также printf
встроенная функция позволяет сохранить полученный результат в переменную
printf -v str 'Hello World\n===========\n'
Оба решения не требуют подоболочки.
Если в следующем вам нужно напечатать строку, вы должны использовать двойные кавычки, как в следующем примере:
echo "$str"
потому что когда вы печатаете строку без кавычек, символы новой строки преобразуются в пробелы.
str=$'Hello World\n===========\n'
? подстановка переменных?
zsh
и ksh
; однако, это НЕ POSIX-совместимый.
str=$"My $PET eats:\n$PET food"
? Этот подход работает для двойных кавычек
Вы можете поместить буквальные символы новой строки в одинарные кавычки (в любой оболочке в стиле Bourne / POSIX).
str='Hello World
===========
'
Для многострочной строки здесь документы часто удобны. Строка подается в качестве ввода в команду.
mycommand <<'EOF'
Hello World
===========
EOF
Если вы хотите сохранить строку в переменной, используйте cat
команду в подстановке команд. Символы новой строки в конце строки будут удалены командой замены. Если вы хотите сохранить последние символы новой строки, поставьте стопор в конце и затем удалите его. В POSIX-совместимых оболочках вы можете писать с str=$(cat <<'EOF'); str=${str%a}
последующим указанием собственно heredoc, но bash требует, чтобы heredoc появлялся перед закрывающей скобкой.
str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}
В ksh, bash и zsh вы можете использовать $'…'
форму в кавычках, чтобы расширить экранирование обратной косой черты внутри кавычек.
str=$'Hello World\n===========\n'
str=$(cat <<'EOF')
не работает как есть .. )
Необходимо поместить на следующую строку после конца документа EOF
... но даже в этом случае он теряет завершающий символ новой строки из-за Command Замена.
\n
экземпляры bash
при захвате here-документа в переменной, рассмотрите IFS= read -r -d '' str <<'EOF'...
в качестве альтернативы подходу с ограничителем (см. мой ответ).
Вы используете "эхо"? Попробуйте "эхо-е".
echo -e "Hello World\n===========\n"
echo
будет добавлен автоматически, если вы не укажете -n. (Однако главный вопрос в том, как получить эти переводы строк в переменную).
bash
, echo -e
делает работу на OS X - это потому , что echo
это Баш встроенный (а не внешний исполняемый файл) и встроенной поддержки делает -e
. ( В качестве встроенной команды, он должен работать на всех платформах , которые Баш бежит на, кстати, echo -e
работает ksh
и zsh
тоже). Напротив, однако, внешняя echo
утилита на OS X /bin/echo
- действительно не поддерживает -e
.
Если вам много раз нужны новые строки в вашем скрипте, вы можете объявить глобальную переменную, содержащую новую строку. Таким образом, вы можете использовать его в строках в двойных кавычках (расширения переменных).
NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
$''
нужна подоболочка?
"My dog eats:${NL}dog food"
Чтобы дополнить великие существующие ответы:
Если вы используете bash
и предпочитаете использовать фактические символы новой строки для удобства чтения , read
это еще один вариант для захвата документа here в переменной , который (как и другие решения здесь) не требует использования подоболочки.
# Reads a here-doc, trimming leading and trailing whitespace.
# Use `IFS= read ...` to preserve it (the trailing \n, here).
read -r -d '' str <<'EOF' # Use `IFS= read ...` to preserve the trailing \n
Hello World
===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"
[Hello World
===========]
-r
гарантирует, что read
не будет интерпретировать ввод (по умолчанию, он будет обрабатывать обратную косую черту специальным образом, но это редко требуется).
-d ''
устанавливает разделитель «запись» в пустую строку, заставляя read
читать весь ввод сразу (вместо одной строки).
Обратите внимание, что, оставив $IFS
(внутренний разделитель полей) по умолчанию $' \t\n'
(пробел, табуляцию, символ новой строки), любой начальный и конечный пробел обрезается по значению, назначенному для него $str
, включая конечный символ новой строки здесь-документа.
(Обратите внимание , что даже если тело здесь-Дока начинается на линию после старта разделителя ( 'EOF'
здесь), он не содержит ведущую строку).
Как правило, это желаемое поведение, но если вы хотите использовать этот завершающий символ новой строки, используйте IFS= read -r -d ''
вместо «просто» read -r -d ''
, но учтите, что все начальные и конечные пробелы сохраняются.
(Обратите внимание, что добавление IFS=
непосредственно к read
команде означает, что назначение действует только во время этой команды, поэтому нет необходимости восстанавливать предыдущее значение.)
Использование here-doc также позволяет при желании использовать отступ для выделения многострочной строки для удобства чтения:
# Caveat: indentation must be actual *tab* characters - spaces won't work.
read -r -d '' str <<-'EOF' # NOTE: Only works if the indentation uses actual tab (\t) chars.
Hello World
===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.
# Note how the leading tabs were stripped.
$ echo "$str"
[Hello World
===========]
Помещение -
между <<
и открывающим разделителем here-doc ( 'EOF'
, здесь) приводит к удалению начальных символов табуляции из тела here-doc и даже к закрывающему разделителю, но обратите внимание, что это работает только с фактическими символами табуляции , а не пробелами, так что если ваш Редактор переводит нажатия клавиш табуляции в пробелы, требуется дополнительная работа.
вам нужно сделать это так:
STR=$(echo -ne "Hello World\n===========\n")
Обновить:
Как указал Фред, таким образом вы потеряете завершающий "\ n". Чтобы назначить переменную с расширенными последовательностями обратной косой черты, выполните:
STR=$'Hello World\n===========\n\n'
давайте проверим это:
echo "[[$STR]]"
дает нам сейчас:
[[Hello World
===========
]]
Обратите внимание, что $ '' отличается от $ "". Второй делает перевод в соответствии с текущей локалью. Для получения более подробной информации см. Раздел ЦИТИРОВАНИЕ в man bash
.
#!/bin/bash
result=""
foo="FOO"
bar="BAR"
result+=$(printf '%s' "$foo")$'\n'
result+=$(printf '%s' "$bar")$'\n'
echo "$result"
printf '%s' "$result"
выход:
FOO
BAR
FOO
BAR
result+=$foo$'\n'
? $(printf %s "$foo")
будет обрезать завершающие символы новой строки, $foo
если таковые имеются.