Vous pouvez utiliser la boucle bash while..do..done pour lire un fichier ligne par ligne sur un système Linux, OSX, *BSD ou de type Unix en utilisant Bash, KSH ou tout autre shell de votre choix.

Niveau de difficulté Facile
Privilèges de la racine Non
Exigences Terminal Linux
Catégorie Scripting shell Linux
Conditions préalables Bash/ksh/zsh/tcsh
Compatibilité avec les systèmes d'exploitation BSD-Linux-macOS-Unix-WSL
Temps de lecture estimé 7 minutes
 

Syntaxe : Lire un fichier ligne par ligne sur un Bash Unix

La syntaxe est la suivante pour bash, ksh, zsh, et tous les autres shells pour lire un fichier ligne par ligne :

  1. while read -r line; do COMMAND; done
  2. Le site -r passée à la commande de lecture empêche les échappements de barres obliques inversées d'être interprétés.
  3. Ajouter IFS= avant la commande de lecture pour éviter que les espaces blancs de début et de fin ne soient coupés.
  4. while IFS= read -r line; do COMMAND_on $line; done

Comment lire un fichier ligne par ligne en Bash ?

Voici une syntaxe plus lisible pour l'homme :

#!/bin/bash
input="/path/to/txt/file"
while IFS= read -r line
do
  echo "$line"
done < "$input"

Le fichier d'entrée ($input) est le nom du fichier que vous devez utiliser par la commande read. La commande de lecture lit le fichier ligne par ligne, en assignant chaque ligne à l'attribut $line variable shell bash. Une fois que toutes les lignes ont été lues depuis le fichier, la boucle while de bash s'arrête. Le séparateur de champs interne (IFS) est défini comme une chaîne vide afin de préserver les espaces blancs. Il s'agit d'une fonctionnalité à sécurité intégrée. Le site -r est utilisée pour ne pas autoriser les antislashes à échapper à des caractères. Veuillez noter que la commande read modifie chaque ligne d'entrée en supprimant tous les caractères d'espacement de tête et de queue tels que les espaces et les tabulations lorsque IFS= est présent avant la commande read. Cependant, si vous souhaitez que les caractères soient supprimés, ne définissez pas IFS= avant la commande read. Par exemple :

#!/bin/bash
input="/path/to/txt/file"
######################################
# $IFS removed to allow the trimming # 
#####################################
while read -r line
do
  echo "$line"
done < "$input"

Comment utiliser la substitution commande/processus pour lire un fichier ligne par ligne

La substitution de processus ou de commande ne signifie rien d'autre que d'exécuter une commande shell et de stocker sa sortie dans une variable ou de la passer à une autre commande. La syntaxe est la suivante :

while IFS= read -r line
do
   ## take some action on $line
  echo "$line"
done < < (command)

Dans cet exemple, exécutez la commande ps avec aux pour répertorier tous les processus, puis les imprimer ou prendre des mesures spécifiques en fonction de vos besoins :

while IFS= read -r line
do
   ## take some action on $line
  echo "$line"
done < <(ps aux)

Utilisation d'une chaîne de caractères ici

Ici, les chaînes de caractères sont comme les documents. Nous pouvons l'utiliser pour alimenter en données notre boucle while en bash. Par exemple :

while IFS= read -r line
do
  # take action on $line #
  echo "$line"
done <<< $(command)
 
while IFS= read -r line
do
  # take action on $line #
  echo "$line"
done <<< $(ps aux)

Voici un exemple de script shell pour effacer ou purger les URL/images Cloudflare à partir de l'interface CLI :

## shell script to purge urls from Cloudflare ##
t="10"
I="/home/vivek/.data/tags.deleted.410" # input file
url=""
while IFS= read -r line
do
        url="$url $line"
done <<<"$(tail -${t} ${I})"
[ "$url" != "" ] && ~/bin/cloudflare.purge.urls.sh "$url"

Comment utiliser un descripteur de fichier (FD) avec la commande de lecture ?

La syntaxe est simple :

input="/path/to/file"
while IFS= read -r -uN line
do
  # do something on $line
  echo "$line"
done N< $input

Voici un exemple de script qui lit depuis le descripteur de fichier FD # 13, au lieu de l'entrée standard comme le clavier ou le fichier :

while IFS= read -r -u13 line
do 
   echo "$line"
done 13<"${input}"
Démonstration de lecture d'un fichier ligne par ligne par Bash

Exemples qui montrent comment lire un fichier ligne par ligne

Voyons quelques exemples supplémentaires sur ce sujet :

#!/bin/ksh
file="/home/vivek/data.txt"
while IFS= read line
do
    # display $line or do something with $line
    echo "$line"
done <"$file"

Le même exemple en utilisant le shell bash :

#!/bin/bash
file="/home/vivek/data.txt"
while IFS= read -r line
do
    # display $line or do somthing with $line
    printf '%sn' "$line"
done <"$file"

Lecture d'une ligne de fichier d'entrée champ par champ

Vous pouvez également lire les champs les uns après les autres. Par exemple, le fichier /etc/passwd comporte un total de sept champs, et nous pouvons les lire un par un comme suit. Tout d'abord, visualisons le fichier en utilisant la commande cat ou more :

cat /etc/passwd
more /etc/passwd

Un exemple de fichier :

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
....
..
....
vivek:x:1000:1000:vivek,,,:/home/vivek:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
nvidia-persistenced:x:127:134:NVIDIA Persistence Daemon,,,:/nonexistent:/usr/sbin/nologin
sshd:x:128:65534::/run/sshd:/usr/sbin/nologin

Dans cet exemple, je vais opérer sur des champs individuels dans chaque ligne en définissant des variables supplémentaires à lire, telles que f1, f2 et ainsi de suite :

#!/bin/bash
file="/etc/passwd"
#
# Each input line divided into seven fields separated by a colon (:) character  
# 
while IFS=: read -r f1 f2 f3 f4 f5 f6 f7
do
        # display fields using f1, f2,..,f7
        printf 'Username: %s, Shell: %s, Home Dir: %sn' "$f1" "$f7" "$f6"
done <"$file"
Fig.01 : Scripting shell Bash - lecture du fichier ligne par ligne - résultats de la démonstration

Fig.01 : Scripting shell Bash - lecture d'un fichier ligne par ligne - résultats de la démonstration

Le séparateur de champs interne (IFS) qui est utilisé pour la division des mots après l'expansion et pour diviser les lignes en mots avec la commande de lecture intégrée.

 

Scripting Bash : Lire un fichier texte ligne par ligne pour créer des fichiers pdf

Mon fichier d'entrée est le suivant (faq.txt) :

4|http://www.cyberciti.biz/faq/mysql-user-creation/|Mysql User Creation: Setting Up a New MySQL User Account
4096|http://www.cyberciti.biz/faq/ksh-korn-shell/|What is UNIX / Linux Korn Shell?
4101|http://www.cyberciti.biz/faq/what-is-posix-shell/|What Is POSIX Shell?
17267|http://www.cyberciti.biz/faq/linux-check-battery-status/|Linux: Check Battery Status Command
17245|http://www.cyberciti.biz/faq/restarting-ntp-service-on-linux/|Linux Restart NTPD Service Command
17183|http://www.cyberciti.biz/faq/ubuntu-linux-determine-your-ip-address/|Ubuntu Linux: Determine Your IP Address
17172|http://www.cyberciti.biz/faq/determine-ip-address-of-linux-server/|HowTo: Determine an IP Address My Linux Server
16510|http://www.cyberciti.biz/faq/unix-linux-restart-php-service-command/|Linux / Unix: Restart PHP Service Command
8292|http://www.cyberciti.biz/faq/mounting-harddisks-in-freebsd-with-mount-command/|FreeBSD: Mount Hard Drive / Disk Command
8190|http://www.cyberciti.biz/faq/rebooting-solaris-unix-server/|Reboot a Solaris UNIX System

Mon script bash :

#!/bin/bash
# Usage: Create pdf files from input (wrapper script)
# Author: Vivek Gite  under GPL v2.x+
#---------------------------------------------------------
 
#Input file
_db="/tmp/wordpress/faq.txt"
 
#Output location
o="/var/www/prviate/pdf/faq"
 
_writer="~/bin/py/pdfwriter.py"
 
# If file exists 
if [[ -f "$_db" ]]
then
    # read it
	while IFS='|' read -r pdfid pdfurl pdftitle
    do
    	local pdf="$o/$pdfid.pdf"
        echo "Creating $pdf file ..."
	#Genrate pdf file
        $_writer --quiet --footer-spacing 2 
        --footer-left "nixCraft is GIT UL++++ W+++ C++++ M+ e+++ d-" 
        --footer-right "Page [page] of [toPage]" --footer-line 
        --footer-font-size 7 --print-media-type "$pdfurl" "$pdf"
    done <"$_db"
fi

Lecture de la variable du shell bash

Disons que vous voulez une liste de tous les paquets php installés sur un Linux Debian ou Ubuntu, entrez :

# My input source is the contents of a variable called $list #
list=$(dpkg --list php* | awk '/ii/{print $2}')
printf '%sn' "$list"

Exemples de résultats :

php-pear
php5-cli
php5-common
php5-fpm
php5-gd
php5-json
php5-memcache
php5-mysql
php5-readline
php5-suhosin-extension

Vous pouvez maintenant lire la liste $ et installer le paquet :

#!/bin/bash
# BASH can iterate over $list variable using a "here string" #
while IFS= read -r pkg
do
    printf 'Installing php package %s...n' "$pkg"
    /usr/bin/apt-get -qq install $pkg
done <<< "$list"
printf '*** Do not forget to run php5enmod and restart the server (httpd or php5-fpm) ***n'

Exemples de résultats :

Installing php package php-pear...
Installing php package php5-cli...
Installing php package php5-common...
Installing php package php5-fpm...
Installing php package php5-gd...
Installing php package php5-json...
Installing php package php5-memcache...
Installing php package php5-mysql...
Installing php package php5-readline...
Installing php package php5-suhosin-extension...
*** Do not forget to run php5enmod and restart the server (httpd or php5-fpm) ***

Conclusion

Cette page explique comment lire un fichier ligne par ligne dans un script shell bash. Consultez les documentations suivantes en utilisant la commande man ou la commande help :

$ man bash
$ man ksh
$ help read

 

Tableau 1 : options de la commande de lecture
-a array Affecte les mots lus à des indices séquentiels de la variable tableau ARRAY, en commençant par zéro.
-d delim Continuez jusqu'à ce que le premier caractère de DELIM soit lu, au lieu de newline.
e Utilisez Readline pour obtenir la ligne.
-i text utiliser TEXT comme texte initial pour Readline.
-n nchars Retourne après avoir lu NCHARS caractères plutôt que d'attendre une nouvelle ligne, mais honore un délimiteur si moins de NCHARS caractères sont lus avant le délimiteur.
-N nchars Retourne seulement après avoir lu exactement NCHARS caractères, à moins que EOF soit rencontré ou que la lecture s'arrête, en ignorant tout délimiteur.
-p prompt Affiche la chaîne PROMPT sans nouvelle ligne de fin avant de tenter de lire.
-r N'autorisez pas les antislashes à échapper à des caractères.
-s Ne pas faire écho à l'entrée provenant d'un terminal.
-t timeout Délai d'attente et retour d'échec si une ligne complète d'entrée n'est pas lue dans les secondes TIMEOUT. La valeur de la variable TMOUT est le délai d'attente par défaut. TIMEOUT peut être un nombre fractionnaire. Si TIMEOUT est égal à 0, read revient immédiatement, sans essayer de lire aucune donnée, et renvoie un succès uniquement si l'entrée est disponible sur le descripteur de fichier spécifié. L'état de sortie est supérieur à 128 si le délai d'attente est dépassé.
-u fd Lire à partir du descripteur de fichier FD au lieu de l'entrée standard.

 

Cette réponse était-elle pertinente? 20 Utilisateurs l'ont trouvée utile (72 Votes)

Powered by WHMCompleteSolution