Quando io faccio
str="Hello World\n===========\n"
Ottengo anche la \n
stampa. Come posso avere newline allora?
Quando io faccio
str="Hello World\n===========\n"
Ottengo anche la \n
stampa. Come posso avere newline allora?
Risposte:
In bash
puoi usare la sintassi
str=$'Hello World\n===========\n'
Le virgolette singole precedute da a $
sono una nuova sintassi che consente di inserire sequenze di escape nelle stringhe.
Inoltre, printf
builtin consente di salvare l'output risultante in una variabile
printf -v str 'Hello World\n===========\n'
Entrambe le soluzioni non richiedono una subshell.
Se di seguito è necessario stampare la stringa, utilizzare virgolette doppie, come nell'esempio seguente:
echo "$str"
perché quando si stampa la stringa senza virgolette, la nuova riga viene convertita in spazi.
str=$'Hello World\n===========\n'
chiama la sintassi ? sostituzione variabile?
zsh
e ksh
; tuttavia, NON è conforme a POSIX.
str=$"My $PET eats:\n$PET food"
. Questo approccio funziona con virgolette doppie
È possibile inserire letteralmente nuove righe tra virgolette singole (in qualsiasi shell in stile Bourne / POSIX).
str='Hello World
===========
'
Per una stringa multilinea, qui i documenti sono spesso convenienti. La stringa viene inserita come input per un comando.
mycommand <<'EOF'
Hello World
===========
EOF
Se si desidera memorizzare la stringa in una variabile, utilizzare il cat
comando in una sostituzione comando. I caratteri di nuova riga alla fine della stringa verranno rimossi dalla sostituzione del comando. Se vuoi conservare le ultime righe finali, metti un tappo alla fine e rimuovilo successivamente. Nelle shell conformi a POSIX, puoi scrivere str=$(cat <<'EOF'); str=${str%a}
seguito dall'ereditarietà corretta, ma bash richiede che l'ereditarietà appaia prima della parentesi di chiusura.
str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}
In ksh, bash e zsh, è possibile utilizzare il $'…'
modulo tra virgolette per espandere le escape di barra rovesciata all'interno delle virgolette.
str=$'Hello World\n===========\n'
str=$(cat <<'EOF')
non funziona così com'è. )
Deve essere posizionato sulla riga successiva dopo la fine del documento EOF
.. ma anche così, perde la nuova riga finale a causa di Command Sostituzione.
\n
istanze finali (e iniziali) bash
quando si acquisisce un here-doc in una variabile, considerare IFS= read -r -d '' str <<'EOF'...
un'alternativa all'approccio stopper (vedere la mia risposta).
Stai usando "echo"? Prova "echo -e".
echo -e "Hello World\n===========\n"
echo
verrà aggiunto automaticamente uno, a meno che non si specifichi -n. (Tuttavia, il peso maggiore della domanda è come inserire queste nuove righe in una variabile).
bash
, echo -e
fa il lavoro su OS X - questo perché echo
è un bash incorporato (piuttosto che un eseguibile esterno) e che integrato sono supportati -e
. (Come un builtin, dovrebbe funzionare su tutte le piattaforme che bash gira su, tra l'altro, echo -e
lavora in ksh
e zsh
troppo). Al contrario, tuttavia, l' utilità esternaecho
su OS X - /bin/echo
- in effetti non supporta -e
.
Se hai bisogno di nuove righe nella tua sceneggiatura molte volte puoi dichiarare una variabile globale che contiene una nuova riga. In questo modo puoi usarlo in stringhe tra virgolette doppie (espansioni variabili).
NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
$''
richiederebbe una subshell?
"My dog eats:${NL}dog food"
Per completare le grandi risposte esistenti:
Se stai usando bash
e preferisci usare le nuove righe effettive per la leggibilità , read
è un'altra opzione per catturare un here-doc in una variabile , che (come altre soluzioni qui) non richiede l'uso di una subshell.
# 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
assicura che read
non interpreti l'input (per impostazione predefinita, tratterebbe le barre rovesciate speciali, ma raramente è necessario).
-d ''
imposta il delimitatore "record" su una stringa vuota, causando la read
lettura dell'intero input in una sola volta (anziché una sola riga).
Si noti che lasciando $IFS
(il separatore di campo interno) al suo valore predefinito, $' \t\n'
(uno spazio, una scheda, una nuova riga), qualsiasi spazio bianco iniziale e finale viene tagliato dal valore assegnato a $str
, che include la nuova riga finale del documento qui.
(Si noti che anche se il corpo del qui-doc inizia sulla linea dopo il delimitatore di partenza ( 'EOF'
qui), esso non contiene un leader di nuova riga).
Di solito, questo è il comportamento desiderato, ma se si desidera quella nuova riga finale, utilizzare IFS= read -r -d ''
invece di solo read -r -d ''
, ma si noti che qualsiasi spazio bianco iniziale e finale viene quindi conservato.
(Notare che anteporre IFS=
direttamente al read
comando significa che l'assegnazione è attiva solo durante quel comando, quindi non è necessario ripristinare il valore precedente.)
L'uso di here-doc consente inoltre di utilizzare facoltativamente il rientro per attivare la stringa multilinea per la leggibilità:
# 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
===========]
Posizionando -
tra <<
e il delimitatore qui-doc di apertura ( 'EOF'
, qui), i caratteri di tabulazione principali vengono rimossi dal corpo del qui-documento e persino dal delimitatore di chiusura, ma nota che questo funziona solo con caratteri di tabulazione effettivi , non spazi, quindi se il tuo editor traduce i tasti premuti nella tabulazione in spazi, è necessario un lavoro extra.
devi farlo in questo modo:
STR=$(echo -ne "Hello World\n===========\n")
Aggiornare:
Come ha sottolineato Fred, in questo modo perderai il finale "\ n". Per assegnare una variabile con sequenze di barre rovesciate espanse, procedere come segue:
STR=$'Hello World\n===========\n\n'
proviamolo:
echo "[[$STR]]"
ci dà ora:
[[Hello World
===========
]]
Nota che $ '' è diverso da $ "". Il secondo esegue la traduzione in base alle impostazioni internazionali correnti. Per i dettagli vedere la sezione PREVENTIVO in man bash
.
#!/bin/bash
result=""
foo="FOO"
bar="BAR"
result+=$(printf '%s' "$foo")$'\n'
result+=$(printf '%s' "$bar")$'\n'
echo "$result"
printf '%s' "$result"
produzione:
FOO
BAR
FOO
BAR
result+=$foo$'\n'
? $(printf %s "$foo")
taglierebbe i caratteri di nuova riga finali $foo
se presenti.