Как называется синтаксис str=$'Hello World\n===========\n'? подстановка переменных?
Зенг
5
@zengr: это называется цитированием ANSI-C , а также поддерживается в zshи ksh; однако, это НЕ POSIX-совместимый.
mklement0
4
@ mkelement0, взятый из ksh93, также поддерживается zsh, bash, mksh и FreeBSD sh, и обсуждается вопрос о
Стефан Шазелас
1
Кажется, не работает с двойными кавычками? например str=$"My $PET eats:\n$PET food"? Этот подход работает для двойных кавычек
Брэд Паркс
31
Вы можете поместить буквальные символы новой строки в одинарные кавычки (в любой оболочке в стиле Bourne / POSIX).
str='Hello World
===========
'
Для многострочной строки здесь документы часто удобны. Строка подается в качестве ввода в команду.
mycommand <<'EOF'HelloWorld===========
EOF
Если вы хотите сохранить строку в переменной, используйте catкоманду в подстановке команд. Символы новой строки в конце строки будут удалены командой замены. Если вы хотите сохранить последние символы новой строки, поставьте стопор в конце и затем удалите его. В POSIX-совместимых оболочках вы можете писать с str=$(cat <<'EOF'); str=${str%a}последующим указанием собственно heredoc, но bash требует, чтобы heredoc появлялся перед закрывающей скобкой.
str=$(cat <<'EOF'HelloWorld===========
a
EOF
); str=${str%a}
В ksh, bash и zsh вы можете использовать $'…'форму в кавычках, чтобы расширить экранирование обратной косой черты внутри кавычек.
Я использую GNU bash 4.1.5, и str=$(cat <<'EOF')не работает как есть .. )Необходимо поместить на следующую строку после конца документа EOF... но даже в этом случае он теряет завершающий символ новой строки из-за Command Замена.
Peter.O
@fred Хорошие моменты, я объяснил о конце новой строки и показал код, который работает в bash. Я думаю, что это ошибка в bash, хотя, если честно, перечитывая спецификацию POSIX, я нахожу неясным, что такое поведение является обязательным, когда << находится внутри подстановки команд, а heredoc - нет.
Жиль "ТАК - перестань быть злым"
Отличный материал; чтобы сохранить конечные (и ведущие) \nэкземпляры bashпри захвате here-документа в переменной, рассмотрите IFS= read -r -d '' str <<'EOF'...в качестве альтернативы подходу с ограничителем (см. мой ответ).
КСТАТИ. Вам не нужен последний \ n, потому что он echoбудет добавлен автоматически, если вы не укажете -n. (Однако главный вопрос в том, как получить эти переводы строк в переменную).
Peter.O
+1 Из всех решений это самое прямое и простое.
Хай Ву
echo -e не работает в OS X
Грег М. Крсак
2
@GregKrsak: В bash, echo -eделает работу на OS X - это потому , что echoэто Баш встроенный (а не внешний исполняемый файл) и встроенной поддержки делает -e. ( В качестве встроенной команды, он должен работать на всех платформах , которые Баш бежит на, кстати, echo -eработает kshи zshтоже). Напротив, однако, внешняя echoутилита на OS X /bin/echo- действительно не поддерживает -e.
mklement0
4
Если вам много раз нужны новые строки в вашем скрипте, вы можете объявить глобальную переменную, содержащую новую строку. Таким образом, вы можете использовать его в строках в двойных кавычках (расширения переменных).
NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
Приятно! Это может быть включено в переменные с использованием двойных кавычек, например"My dog eats:${NL}dog food"
Брэд Паркс
Это сработало для меня. При использовании сценария bash для компоновки строки, которая автоматически копируется в буфер обмена для последующего вставки в другом месте, этот подход работал для добавления новых строк в результирующий вывод.
Вилле
3
Из всего обсуждения вот самый простой способ для меня:
bash$ str="Hello World
==========="
bash$ echo "$str"HelloWorld===========
Команда echo должна использовать двойные кавычки .
Если вы используете 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 \nHelloWorld===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"[HelloWorld===========]
-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.HelloWorld===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.# Note how the leading tabs were stripped.
$ echo "$str"[HelloWorld===========]
Помещение -между <<и открывающим разделителем here-doc ( 'EOF', здесь) приводит к удалению начальных символов табуляции из тела here-doc и даже к закрывающему разделителю, но обратите внимание, что это работает только с фактическими символами табуляции , а не пробелами, так что если ваш Редактор переводит нажатия клавиш табуляции в пробелы, требуется дополнительная работа.
Как указал Фред, таким образом вы потеряете завершающий "\ n". Чтобы назначить переменную с расширенными последовательностями обратной косой черты, выполните:
STR=$'Hello World\n===========\n\n'
давайте проверим это:
echo "[[$STR]]"
дает нам сейчас:
[[HelloWorld===========]]
Обратите внимание, что $ '' отличается от $ "". Второй делает перевод в соответствии с текущей локалью. Для получения более подробной информации см. Раздел ЦИТИРОВАНИЕ в man bash.
Ответы:
В
bash
вы можете использовать синтаксисОдинарные кавычки,
$
начинающиеся с символа a, - это новый синтаксис, который позволяет вставлять escape-последовательности в строки.Также
printf
встроенная функция позволяет сохранить полученный результат в переменнуюОба решения не требуют подоболочки.
Если в следующем вам нужно напечатать строку, вы должны использовать двойные кавычки, как в следующем примере:
потому что когда вы печатаете строку без кавычек, символы новой строки преобразуются в пробелы.
источник
str=$'Hello World\n===========\n'
? подстановка переменных?zsh
иksh
; однако, это НЕ POSIX-совместимый.str=$"My $PET eats:\n$PET food"
? Этот подход работает для двойных кавычекВы можете поместить буквальные символы новой строки в одинарные кавычки (в любой оболочке в стиле Bourne / POSIX).
Для многострочной строки здесь документы часто удобны. Строка подается в качестве ввода в команду.
Если вы хотите сохранить строку в переменной, используйте
cat
команду в подстановке команд. Символы новой строки в конце строки будут удалены командой замены. Если вы хотите сохранить последние символы новой строки, поставьте стопор в конце и затем удалите его. В POSIX-совместимых оболочках вы можете писать сstr=$(cat <<'EOF'); str=${str%a}
последующим указанием собственно heredoc, но bash требует, чтобы heredoc появлялся перед закрывающей скобкой.В ksh, bash и zsh вы можете использовать
$'…'
форму в кавычках, чтобы расширить экранирование обратной косой черты внутри кавычек.источник
str=$(cat <<'EOF')
не работает как есть ..)
Необходимо поместить на следующую строку после конца документаEOF
... но даже в этом случае он теряет завершающий символ новой строки из-за Command Замена.\n
экземплярыbash
при захвате here-документа в переменной, рассмотритеIFS= read -r -d '' str <<'EOF'...
в качестве альтернативы подходу с ограничителем (см. мой ответ).Вы используете "эхо"? Попробуйте "эхо-е".
источник
echo
будет добавлен автоматически, если вы не укажете -n. (Однако главный вопрос в том, как получить эти переводы строк в переменную).bash
,echo -e
делает работу на OS X - это потому , чтоecho
это Баш встроенный (а не внешний исполняемый файл) и встроенной поддержки делает-e
. ( В качестве встроенной команды, он должен работать на всех платформах , которые Баш бежит на, кстати,echo -e
работаетksh
иzsh
тоже). Напротив, однако, внешняяecho
утилита на OS X/bin/echo
- действительно не поддерживает-e
.Если вам много раз нужны новые строки в вашем скрипте, вы можете объявить глобальную переменную, содержащую новую строку. Таким образом, вы можете использовать его в строках в двойных кавычках (расширения переменных).
источник
$''
нужна подоболочка?"My dog eats:${NL}dog food"
Из всего обсуждения вот самый простой способ для меня:
Команда echo должна использовать двойные кавычки .
источник
Чтобы дополнить великие существующие ответы:
Если вы используете
bash
и предпочитаете использовать фактические символы новой строки для удобства чтения ,read
это еще один вариант для захвата документа here в переменной , который (как и другие решения здесь) не требует использования подоболочки.-r
гарантирует, чтоread
не будет интерпретировать ввод (по умолчанию, он будет обрабатывать обратную косую черту специальным образом, но это редко требуется).-d ''
устанавливает разделитель «запись» в пустую строку, заставляяread
читать весь ввод сразу (вместо одной строки).Обратите внимание, что, оставив
$IFS
(внутренний разделитель полей) по умолчанию$' \t\n'
(пробел, табуляцию, символ новой строки), любой начальный и конечный пробел обрезается по значению, назначенному для него$str
, включая конечный символ новой строки здесь-документа.(Обратите внимание , что даже если тело здесь-Дока начинается на линию после старта разделителя (
'EOF'
здесь), он не содержит ведущую строку).Как правило, это желаемое поведение, но если вы хотите использовать этот завершающий символ новой строки, используйте
IFS= read -r -d ''
вместо «просто»read -r -d ''
, но учтите, что все начальные и конечные пробелы сохраняются.(Обратите внимание, что добавление
IFS=
непосредственно кread
команде означает, что назначение действует только во время этой команды, поэтому нет необходимости восстанавливать предыдущее значение.)Использование here-doc также позволяет при желании использовать отступ для выделения многострочной строки для удобства чтения:
Помещение
-
между<<
и открывающим разделителем here-doc ('EOF'
, здесь) приводит к удалению начальных символов табуляции из тела here-doc и даже к закрывающему разделителю, но обратите внимание, что это работает только с фактическими символами табуляции , а не пробелами, так что если ваш Редактор переводит нажатия клавиш табуляции в пробелы, требуется дополнительная работа.источник
вам нужно сделать это так:
Обновить:
Как указал Фред, таким образом вы потеряете завершающий "\ n". Чтобы назначить переменную с расширенными последовательностями обратной косой черты, выполните:
давайте проверим это:
дает нам сейчас:
Обратите внимание, что $ '' отличается от $ "". Второй делает перевод в соответствии с текущей локалью. Для получения более подробной информации см. Раздел ЦИТИРОВАНИЕ в
man bash
.источник
выход:
источник
result+=$foo$'\n'
?$(printf %s "$foo")
будет обрезать завершающие символы новой строки,$foo
если таковые имеются.