Když dělám
str="Hello World\n===========\n"
Dostanu \n
vytištěno také. Jak tedy mohu mít nové řádky?
V bash
můžete použít syntaxi
str=$'Hello World\n===========\n'
Jednotlivé nabídky, kterým předchází $
je nová syntaxe, která umožňuje vkládat escape řetězce do řetězců.
Také zabudovaný printf
umožňuje uložit výsledný výstup do proměnné
printf -v str 'Hello World\n===========\n'
Obě řešení nevyžadují subshell.
Pokud v následujícím textu potřebujete vytisknout řetězec, měli byste použít dvojité uvozovky, jako v následujícím příkladu:
echo "$str"
protože při tisku řetězce bez uvozovek se nový řádek převede na mezery.
Do jediných uvozovek můžete vložit doslovné řádky (v jakémkoli stylu Shell Bourne/POSIX).
str='Hello World
===========
'
Pro víceřádkový řetězec jsou často zde dokumenty . Řetězec je přiváděn jako vstup do příkazu.
mycommand <<'EOF'
Hello World
===========
EOF
Pokud chcete řetězec uložit do proměnné, použijte příkaz cat
v substituci příkazu. Znaky nového řádku na konci řetězce budou odstraněny nahrazením příkazu. Pokud si chcete zachovat poslední řádky, položte na konec zátku a poté ji odtáhněte. V shellech kompatibilních s POSIXem můžete napsat str=$(cat <<'EOF'); str=${str%a}
následovaný vlastním heredocem, ale bash vyžaduje, aby se heredoc objevil před závěrečnou závorkou.
str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}
V ksh, bash a zsh můžete pomocí citovaného formuláře $'…'
Rozbalit úniky zpětného lomítka uvnitř uvozovek.
str=$'Hello World\n===========\n'
Používáte echo? Zkuste "echo -e".
echo -e "Hello World\n===========\n"
Pokud potřebujete ve svém skriptu nové řádky mnohokrát, můžete deklarovat globální proměnnou obsahující nový řádek. Tímto způsobem ji můžete použít ve dvojitě uvězněných řetězcích (variabilní rozšíření).
NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
Doplnění skvělých existujících odpovědí:
Pokud používáte bash
a dáváte přednost použití aktuálních nových řádků pro čitelnost, read
je další možnost pro zachycení here-doc v proměnné, což (stejně jako jiná řešení zde) nevyžaduje použití podshell.
# 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
zajišťuje, že read
neinterpretuje vstup (ve výchozím nastavení by zacházelo se speciálními zpětnými lomítky, ale to je zřídka nutné).
-d ''
nastaví oddělovač „záznamu“ na prázdný řetězec, což způsobí, že read
přečte celý celý vstup najednou (namísto pouze jednoho řádku).
Všimněte si, že ponecháním $IFS
(interní oddělovač pole) ve výchozím nastavení, $' \t\n'
(mezera, karta, nový řádek), jakýkoli úvodní a koncový mezera je oříznut z hodnoty přiřazené $str
, která obsahuje koncový nový řádek here-doc.
(Všimněte si, že i když se tělo tohoto dokumentu začíná na řádku za oddělovačem začátku ('EOF'
zde), neobsahuje úvodní úvodní nový řádek).
Obvykle se jedná o požadované chování, ale pokud chcete, aby koncové řádky, použijte IFS= read -r -d ''
místo pouhého read -r -d ''
, ale uvědomte si, že je zachován jakýkoli úvodní a koncový mezerník.
(Všimněte si, že se připravuje IFS=
přímo k příkazu read
znamená, že přiřazení platí pouze během tohoto příkazu, takže není třeba obnovit předchozí hodnotu.)
Použití dokumentu Here-doc také umožňuje volitelně použít odsazení a nastavit víceřádkový řetězec pro čitelnost:
# 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
===========]
Umístění -
mezi <<
a oddělovač zde-doc ('EOF'
, zde) způsobuje, že vedoucí znaky tabulátoru budou odstraněny z těla here-doc a dokonce i oddělovače, ale nezapomeňte, že tato funguje pouze s skutečnou kartou postavy, nikoli mezery, takže pokud váš editor překládá klávesové zkratky na kartě do mezer, je zapotřebí další práce.
Ze všech diskusí je pro mě nejjednodušší způsob:
bash$ str="Hello World
==========="
bash$ echo "$str"
Hello World
===========
Příkaz echo musí používat dvojité uvozovky.