
Lors de l'écriture de scripts Bash, vous vous retrouverez parfois dans des situations où vous devrez lire un fichier ligne par ligne. Par exemple, vous pouvez avoir un fichier texte contenant des données qui doivent être traitées par le script.
Dans ce tutoriel, nous verrons comment lire un fichier ligne par ligne dans Bash.
Lecture d'un fichier ligne par ligne Syntaxe #
La syntaxe la plus générale pour lire un fichier ligne par ligne est la suivante :
while IFS= read -r line; do
printf '%s\n' "$line"
done < input_file
ou la version monoligne équivalente :
while IFS= read -r line; do printf '%s\n' "$line"; done < input_file
Comment ça marche ?
Le fichier d'entrée (input_file
) est le nom du fichier redirigé vers la boucle while. Le read
La commande traite le fichier ligne par ligne, en affectant chaque ligne à la line
variable. Une fois toutes les lignes traitées, la boucle while se termine.
Par défaut, le read
La commande interprète la barre oblique inverse comme un caractère d'échappement et supprime tous les espaces blancs de début et de fin, ce qui peut parfois provoquer un comportement inattendu. Pour désactiver l'échappement antislash, nous invoquons la commande avec le -r
option, et pour désactiver le rognage, le séparateur de champ interne (IFS
) est effacé.
Nous utilisons [printf
] au lieu de echo
pour rendre le code plus portable et éviter les comportements indésirables. Par exemple, si la ligne contient des valeurs telles que "-e", elle sera traitée comme une option d'écho.
Exemples de lecture d'un fichier ligne par ligne #
Jetons un coup d'œil à l'exemple suivant. Supposons que nous ayons un fichier nommé distros.txt
contenant une liste de certaines des distributions Linux les plus populaires, et leurs gestionnaires de packages séparés par des virgules (,
):
Ubuntu,apt
Debian,apt
CentOS,yum
Arch Linux,pacman
Fedora,dnf
Pour lire le fichier ligne par ligne, vous exécuteriez le code suivant dans votre terminal :
while IFS= read -r line; do
printf '%s\n' "$line"
done < distros.txt
Le code lit le fichier ligne par ligne, affecte chaque ligne à une variable et l'imprime. Fondamentalement, vous verriez la même sortie que si vous affichiez le contenu du fichier en utilisant le cat
commande.
Et si vous voulez imprimer uniquement les distributions qui utilisent apt ? Une façon serait d'utiliser le if
instructionet vérifiez si la ligne contient la sous-chaîne apt :
while IFS= read -r line; do
if [[ "$line" == *"apt"* ]]; then
printf '%s\n' "$line"
fi
done < distros.txt
Ubuntu,apt
Debian,apt
Lors de la lecture d'un fichier ligne par ligne, vous pouvez également passer plus d'une variable au read
commande, qui divisera la ligne en champs basés sur IFS
. Le premier champ est affecté à la première variable, le deuxième à la deuxième variable, et ainsi de suite. S'il y a plus de champs que de variables, les champs restants sont affectés à la dernière variable.
Dans l'exemple suivant, nous définissons IFS
à une virgule (,
) et passez deux variables distro
et pm
au read
commande. Tout depuis le début de la ligne jusqu'à la première virgule sera assigné à la première variable (distro
), et le reste de la ligne sera affecté à la seconde variable (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
Méthodes alternatives de lecture de fichiers #
Utilisation d'un numéro de substitution de processus
La substitution de processus est une fonctionnalité qui vous permet d'utiliser la sortie de la commande sous forme de fichier :
while IFS= read -r line; do
printf '%s\n' "$line"
done < <(cat input_file )
Utiliser une chaîne Here #
Here String est une variante du document Here. La chaîne (cat input_file )
conserve les retours à la ligne :
while IFS= read -r line; do
printf '%s\n' "$line"
done <<< $(cat input_file )
Utilisation du descripteur de fichier #
Vous pouvez également fournir l'entrée à la boucle à l'aide d'un descripteur de fichier :
while IFS= read -r -u9 line; do
printf '%s\n' "$line"
done 9< input_file
Lorsque vous travaillez avec des descripteurs de fichiers, utilisez un nombre compris entre 4 et 9 pour éviter tout conflit avec les descripteurs de fichiers internes du shell.
Conclusion #
Dans Bash, nous pouvons lire un fichier ligne par ligne en utilisant une boucle while et le read
commande.
Si vous avez des questions ou des commentaires, n'hésitez pas à laisser un commentaire.