Voglio scrivere alcuni testi predefiniti in un file con il seguente:
text="this is line one\n
this is line two\n
this is line three"
echo -e $text > filename
Mi aspetto qualcosa del genere:
this is line one
this is line two
this is line three
Ma capito:
this is line one
this is line two
this is line three
Sono sicuro che non ci sia spazio dopo ogni \n
, ma come viene fuori lo spazio extra?
Heredoc sembra più conveniente per questo scopo. È usato per inviare comandi multipli a un programma interprete di comandi come ex o cat
cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage
La stringa dopo "<<" indica dove fermarsi.
Per inviare queste righe a un file, utilizzare:
cat > $FILE <<- EOM
Line 1.
Line 2.
EOM
Puoi anche memorizzare queste righe su una variabile:
read -r -d '' VAR << EOM
This is line 1.
This is line 2.
Line 3.
EOM
Memorizza le righe alla variabile denominata VAR
.
Durante la stampa, ricorda le virgolette attorno alla variabile altrimenti non vedrai i caratteri di nuova riga.
echo "$VAR"
Ancora meglio, puoi usare il rientro per farlo risaltare maggiormente nel tuo codice. Questa volta basta aggiungere un "-" dopo "<<" per interrompere la visualizzazione delle schede.
read -r -d '' VAR <<- EOM
This is line 1.
This is line 2.
Line 3.
EOM
Ma poi devi usare tabulazioni, non spazi, per il rientro nel tuo codice.
Se stai cercando di ottenere la stringa in una variabile, un altro modo semplice è qualcosa del genere:
USAGE=$(cat <<-END
This is line one.
This is line two.
This is line three.
END
)
Se rientri la stringa con le schede (ad es., "\ T"), la rientranza verrà eliminata. Se rientri con spazi, verrà lasciato il rientro.
NOTA: It is significativo che l'ultima parentesi chiusa si trova su un'altra riga. Il testo END
deve apparire su una riga da solo.
echo
aggiunge spazi tra gli argomenti passati ad esso. $text
è soggetto a espansione variabile e suddivisione in parole, quindi il comando echo
equivale a:
echo -e "this" "is" "line" "one\n" "this" "is" "line" "two\n" ...
Puoi vedere che uno spazio verrà aggiunto prima di "questo". Puoi rimuovere i caratteri di nuova riga e citare $text
per preservare le nuove righe:
text="this is line one
this is line two
this is line three"
echo "$text" > filename
Oppure puoi usare printf
, che è più robusto e portatile di echo
:
printf "%s\n" "this is line one" "this is line two" "this is line three" > filename
In bash
, che supporta l'espansione delle parentesi graffe, si potrebbe anche fare:
printf "%s\n" "this is line "{one,two,three} > filename
in uno script bash i seguenti lavori:
#!/bin/sh
text="this is line one\nthis is line two\nthis is line three"
echo $text > filename
in alternativa:
text="this is line one
this is line two
this is line three"
echo "$text" > filename
nome del file cat dà:
this is line one
this is line two
this is line three
Ho trovato più soluzioni poiché volevo che ogni riga fosse rientrata correttamente:
Puoi usare echo
:
echo "this is line one" \
"\n""this is line two" \
"\n""this is line three" \
> filename
Non funziona se si inserisce "\n"
appena prima di \
alla fine di una riga.
In alternativa, puoi usare printf
per una migliore portabilità (mi è capitato di avere molti problemi con echo
):
printf '%s\n' \
"this is line one" \
"this is line two" \
"this is line three" \
> filename
Un'altra soluzione potrebbe essere:
text=''
text="${text}this is line one\n"
text="${text}this is line two\n"
text="${text}this is line three\n"
printf "%b" "$text" > filename
o
text=''
text+="this is line one\n"
text+="this is line two\n"
text+="this is line three\n"
printf "%b" "$text" > filename
Un'altra soluzione è ottenuta mescolando printf
e sed
.
if something
then
printf '%s' '
this is line one
this is line two
this is line three
' | sed '1d;$d;s/^ //g'
fi
Non è facile effettuare il refactoring del codice formattato in questo modo mentre si codifica il codice di indentazione nel codice.
È possibile utilizzare una funzione di supporto e alcuni trucchi di sostituzione variabili:
unset text
_() { text="${text}${text+
}${*}"; }
# That's an empty line which demonstrates the reasoning behind
# the usage of "+" instead of ":+" in the variable substitution
# above.
_ ""
_ "this is line one"
_ "this is line two"
_ "this is line three"
unset -f _
printf '%s' "$text"
funzionerà se lo metti come di seguito:
AA='first line
\nsecond line
\nthird line'
echo $AA
output:
first line
second line
third line
Quello che segue è il mio modo preferito per assegnare una stringa multi-linea a una variabile (penso che appaia carina).
read -r -d '' my_variable << \
_______________________________________________________________________________
String1
String2
String3
...
StringN
_______________________________________________________________________________
Il numero di caratteri di sottolineatura è lo stesso (qui 80) in entrambi i casi.