Questo è trattato nella voce Bash FAQ sul reading data line-by-line.
Il comando di lettura modifica ogni riga letta; per impostazione predefinita rimuove tutti i caratteri di spaziatura iniziale e finale (spazi e tabulazioni o eventuali caratteri di spaziatura presenti in IFS). Se questo non è desiderato, la variabile IFS deve essere eliminato:
# Exact lines, no trimming
while IFS= read -r line; do
printf '%s\n' "$line"
done < "$file"
Come Charles Duffy fa giustamente notare (e io avevo perso, concentrandosi sul problema IFS
); se vuoi vedere gli spazi nel tuo output devi anche citare la variabile quando la usi o la shell, ancora una volta, cancella gli spazi bianchi.
Note su alcune delle altre differenze in questo frammento tra virgolette rispetto al codice originale.
L'utilizzo dell'argomento -r
su read
è coperto in una singola frase nella parte superiore della pagina precedentemente collegata.
L'opzione -r da leggere impedisce l'interpretazione del backslash (solitamente utilizzata come coppia di backline backslash, per continuare su più righe). Senza questa opzione, le barre retroverse nell'input verranno scartate. Dovresti quasi sempre usare l'opzione -r con read.
Per quanto riguarda utilizzando printf
invece di echo
là del comportamento di echo
è, in qualche modo, purtroppo, non è portabile coerenti in tutti gli ambienti e le differenze possono essere difficile da affrontare. printf
d'altra parte è coerente e può essere utilizzato interamente in modo robusto.
fonte
2015-04-17 02:26:42
Se non si fornisce 'read' alcun argomento da usare per contenere l'input (basandosi sulla variabile di default' REPLY'), non viene eliminato lo spazio vuoto e si può omettere la modifica a 'IFS'. Cioè, 'mentre leggi -r; do printf '% s \ n' "$ RISPONDI"; done <"$ file" ' – chepner
@chepner Interessante. Mi chiedo perché sia così. –
Non ne sono sicuro; non sembra essere documentato per quanto posso dire. Ha un certo senso se ci si pensa come argomenti zero richiedono dividere la linea in campi zero, il che significa che non c'è alcun uso di 'IFS'. (Questo presuppone che tu accetti che spaccare una linea in un campo sia ancora una divisione, anche se degenerata.) In ogni caso, è un 'bash'ism; POSIX 'read' richiede almeno un argomento. – chepner