Iterazione su stringa a più righe memorizzata in variabile


17

Ho letto che è male scrivere cose come for line in $(command), invece sembra essere il modo corretto:

command | while IFS= read -r line; do echo $line; done

Funziona benissimo. Ma cosa succede se ciò su cui voglio iterare è il contenuto di una variabile , non il risultato diretto di un comando?

Ad esempio, immagina di creare il seguente file quickfox:

The quick brown
foxjumps\ over -
the
lazy ,
dog.

Vorrei poter fare qualcosa del genere:

# This is just for the example,
# I could of course stream the contents to `read`
variable=$(cat quickfox);
while IFS= read -r line < $variable; do echo $line; done; # this is incorrect

Risposte:


19

Nelle shell moderne come bash e zsh, hai un redirector `<<< 'molto utile che accetta una stringa come input. Quindi lo faresti

while IFS= read -r line ; do echo $line; done <<< "$variable"

Altrimenti, puoi sempre fare

echo "$variable" | while IFS= read -r line ; do echo $line; done

Scusa, avrei dovuto pensare di fare eco ai contenuti, ovviamente. Ma grazie per la risposta veloce comunque!
Sheljohn,

1
devi $variableusare una doppia virgoletta quando la usi, altrimenti il whileloop riceverà solo una riga di input. Si veda, ad esempio, la differenza in uscita tra echo $variablevs echo "$variable"o cat <<< $variablecontro cat <<< "$variable".
Cas

@cas In realtà dipende da cosa c'è dentro la variabile $. Nel caso presentato dall'OP ("variabile = $ (cat quickfox)") funziona senza le virgolette aggiuntive. Ma per il caso generale, hai ragione. Modifica la mia risposta. Grazie.
Lgeorget,

La variable=$(cat quickfox)stessa domanda del PO fornisce un esempio di cosa stavo parlando. L'utilizzo $variableall'interno di virgolette doppie include le nuove righe, l'utilizzo senza che le nuove righe vengano tradotte in spazi dalla shell. Se stai leggendo ed elaborando riga per riga, questo fa una differenza enorme: con il primo hai più linee di input, con il secondo hai solo una riga di input. I dati di input sono superficialmente simili ma, in pratica, completamente diversi in questi due casi.
Caso

ad esempio: con tali dati di input, cat <<< "$variable" | wc -lrestituisce 5. cat <<< $variable | wc -lrestituisce 1. Se si desidera / è necessario conservare gli spazi bianchi (inclusi newline, tab, spazi singoli o multipli) in una variabile, è NECESSARIO citare due volte la variabile quando la si utilizza, altrimenti saranno tutti trasformati in un unico spazio tra ogni "parola".
Caso
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.