Коли я це роблю
str="Hello World\n===========\n"
Я отримую \n
надруковані теж. Як я можу мати нові рядки тоді?
Коли я це роблю
str="Hello World\n===========\n"
Я отримую \n
надруковані теж. Як я можу мати нові рядки тоді?
Відповіді:
У bash
ви можете використовувати синтаксис
str=$'Hello World\n===========\n'
Одиночні лапки, що передує a, $
- це новий синтаксис, який дозволяє вставляти послідовності втечі.
Також 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}
подальшим відповідним гередоком, але bash вимагає, щоб гередок з'явився перед дужками, що закриваються.
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-doc у змінній, розглянемо IFS= read -r -d '' str <<'EOF'...
як альтернативу стоп-підходу (див. мою відповідь).
Ви використовуєте "ехо"? Спробуйте "ехо -е".
echo -e "Hello World\n===========\n"
echo
він автоматично додасть його, якщо ви не вкажете -n. (Однак, основним питанням є те, як перетворити ці нові рядки в змінну).
bash
, echo -e
робить роботу на OS X - це тому , що echo
це Баш вбудований (а не зовнішній виконуваний файл) і вбудованою підтримки робить -e
. (Як вбудований, він повинен працювати на всіх платформах, на яких працює bash; до речі, 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
є ще одним варіантом захоплення тут-док в змінну , яка (як і інші рішення тут) не вимагає використання підзаголовка.
# 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
, що включає в себе зворотний новий рядок тут-doc.
(Зауважте, що незважаючи на те, що тіло here-doc починається на лінії після розмежувача старту ( 'EOF'
тут), воно не містить провідного нового рядка).
Зазвичай, це бажана поведінка, але якщо ви хочете, щоб цей трейлінг нового рядка був використаний, IFS= read -r -d ''
а не просто read -r -d ''
, але зауважте, що будь-яка провідна та відстала пробіли зберігається.
(Зауважте, що попереднє додавання IFS=
безпосередньо до read
команди означає, що присвоєння діє лише під час цієї команди, тому не потрібно відновлювати попереднє значення.)
Використання тут-документа також дозволяє необов'язково використовувати відступ, щоб відкласти багаторядковий рядок для читабельності:
# 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
===========]
Розміщення -
між <<
роздільником та відкриттям тут-doc-роздільником ( 'EOF'
, тут) призводить до позбавлення провідних символів вкладки з тіла тут-документа і навіть відмежувача, що закривається, але зауважте, що це працює лише з фактичними символами вкладки , а не з пробілами, тому якщо ваш редактор переводить натискання клавіш вкладки на пробіли, потрібна додаткова робота.
вам потрібно зробити це так:
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
якщо такі є.