
Quando si scrivono script Bash, a volte ci si trova in situazioni in cui è necessario leggere un file riga per riga. Ad esempio, potresti avere un file di testo contenente dati che dovrebbero essere elaborati dallo script.
In questo tutorial, discuteremo come leggere un file riga per riga in Bash.
Lettura di un file riga per riga Sintassi #
La sintassi più generale per leggere un file riga per riga è la seguente:
while IFS= read -r line; do
printf '%s\n' "$line"
done < input_file
o la versione equivalente a riga singola:
while IFS= read -r line; do printf '%s\n' "$line"; done < input_file
Come funziona?
Il file di input (input_file
) è il nome del file reindirizzato al ciclo while. Il read
command elabora il file riga per riga, assegnando ogni riga alla line
variabile. Una volta che tutte le righe sono state elaborate, il ciclo while termina.
Per impostazione predefinita, il read
Il comando interpreta la barra rovesciata come un carattere di escape e rimuove tutti gli spazi bianchi iniziali e finali, che a volte possono causare comportamenti imprevisti. Per disabilitare l'escape della barra rovesciata, stiamo invocando il comando con il -r
opzione, e per disabilitare il taglio, il separatore di campo interno (IFS
) è cancellato.
Stiamo usando [printf
] invece di echo
per rendere il codice più portabile ed evitare comportamenti indesiderati. Ad esempio, se la riga contiene valori come "-e", verrà trattata come un'opzione di eco.
Lettura di un file riga per riga Esempi #
Diamo un'occhiata al seguente esempio. Supponiamo di avere un file chiamato distros.txt
contenente un elenco di alcune delle distribuzioni Linux più popolari e i relativi gestori di pacchetti separati da virgole (,
):
Ubuntu,apt
Debian,apt
CentOS,yum
Arch Linux,pacman
Fedora,dnf
Per leggere il file riga per riga, dovresti eseguire il seguente codice nel tuo terminale:
while IFS= read -r line; do
printf '%s\n' "$line"
done < distros.txt
Il codice legge il file per riga, assegna ogni riga a una variabile e la stampa. Fondamentalmente, vedresti lo stesso output come se dovessi visualizzare il contenuto del file usando il cat
comando.
E se volessi stampare solo le distribuzioni che usano apt? Un modo sarebbe usare if
istruzione e controlla se la riga contiene la sottostringa apt:
while IFS= read -r line; do
if [[ "$line" == *"apt"* ]]; then
printf '%s\n' "$line"
fi
done < distros.txt
Ubuntu,apt
Debian,apt
Quando leggi un file riga per riga, puoi anche passare più di una variabile a read
comando, che dividerà la riga in campi basati su IFS
. Il primo campo è assegnato alla prima variabile, il secondo alla seconda variabile e così via. Se ci sono più campi che variabili, i campi rimanenti vengono assegnati all'ultima variabile.
Nell'esempio seguente, impostiamo IFS
in una virgola (,
) e passare due variabili distro
e pm
al read
comando. Tutto dall'inizio della riga fino alla prima virgola verrà assegnato alla prima variabile (distro
), e il resto della riga verrà assegnato alla seconda variabile (pm
):
while IFS=, read -r distro pm; do
printf '%s is the package manager for %s\n' "$pm" "$distro"
done < distros.txt
apt is the package manager for Ubuntu
apt is the package manager for Debian
yum is the package manager for CentOS
pacman is the package manager for Arch Linux
dnf is the package manager for Fedora
Metodi di lettura file alternativi #
Utilizzo di una sostituzione di processo #
La sostituzione del processo è una funzionalità che consente di utilizzare l'output del comando come file:
while IFS= read -r line; do
printf '%s\n' "$line"
done < <(cat input_file )
Utilizzo di una stringa Here #
Here String è una variante del documento Here. La stringa (cat input_file )
mantiene le nuove righe:
while IFS= read -r line; do
printf '%s\n' "$line"
done <<< $(cat input_file )
Utilizzo del descrittore file #
Puoi anche fornire l'input per il ciclo usando un descrittore di file:
while IFS= read -r -u9 line; do
printf '%s\n' "$line"
done 9< input_file
Quando si lavora con i descrittori di file, utilizzare un numero compreso tra 4 e 9 per evitare conflitti con i descrittori di file interni della shell.
Conclusione #
In Bash, possiamo leggere un file riga per riga usando un ciclo while e read
comando.
Se hai domande o feedback, sentiti libero di lasciare un commento.