Lecture de fichiers en Bash


Il existe différentes techniques de lecture des fichier en bash. Par lecture, j'entends la capacité d'accéder à tout ou partie d'un fichier pour effectuer un traitement (copie dans une variable, suppression de caractère etc.)

1. Lignes par lignes

1.1. Techique 1 ( cat + pipe + while + read )


cat fichier | while  read ligne ; do
  ... 
  echo $ligne
  ...
done


Explications :

  1. la commande cat fichier va envoyer le contenu du fichier vers la sortie standard.

  2. Ici, un tube | (ou pipe en anglais) permet de re diriger les données destinées à la sortie standard (i.e. Le résultats de cat fichier) vers l'entrée standard de la commande suivante.

  3. La commande suivante est ici une boucle while, qui lit sur son entrée standard grace à la commande read. Read lit ligne par ligne. A chaque itération de la boucle while, une nouvelle ligne est copiée dans la variable ligne.

  4. A la fin du fichier, la commande cat vas envoyer un signal « End Of File » vers la sortie standard. Ce signal, est alors capté par la commande read qui retourne alors la valeur 1, ce qui rend négatif le test effectuer par l'opérateur while. (essayer read puis CTRL+D puis echo $?)


Remarque : le code suivant ne permet pas de calculer le nombre de lignes du fichier essai.txt. Pouvez-vous expliquer ce qui a bien pu se passer ?


$ cat essai.txt
3 2 1
5
4 6
$ i=0;cat essai.txt|while read ligne; do i=$((i+1)); done; echo $i
0 

1.2 Technique 2 ( while + read + redirection de stdout)

#! /bin/bash  

while read line  
do   
   echo -e "$line\n"  
done < file.txt



Les instructions en ligne de commande se présentes comme suit :

while read line; do echo -e "$line\n"; done < file.txt

Exemple : on peut compter le nombre de lignes du fichier essai.txt précédent par :
$ i=0; while read ligne; do i=$((i+1)); done < essai.txt; echo $i
3

1.3. Autre :


Rappel : la variable IFS « Internal Field Separator » indique à BASH quel(s) caractère(s) considérer comme séparateur de champs. Dans le code qui suit, nous avons modifié la valeur par défaut et fixé le séparateur de champs comme étant le Retour Chariot. Nous pouvons de la sorte utiliser la commande cat sur le fichier


old_IFS=$IFS  # sauvegarde du séparateur de champ  
IFS=$'\n'     # nouveau séparateur de champ, le caractère fin de ligne  
for ligne in $(cat fichier)  
do  
   commande  
done  
IFS=$old_IFS  # rétablissement du séparateur de champ par défaut



2. Mot par mot:


#!/bin/bash
for WORD in `cat filename`
do
    echo $WORD
done


Les instructions en ligne de commande :

for mot in $(cat file.txt); do echo "$mot" ; done  


Sources :


Lecture http://www.commentcamarche.net/faq/5027-comment-lire-un-fichier-ligne-par-ligne

Sur IFS http://michauko.org/blog/2009/01/15/ifs-separateurs-scripts-bash/

Tableau http://mandrivausers.org/index.php?/topic/21998-reading-a-text-file-line-by-line-with-bash/

True EOF http://stackoverflow.com/questions/463913/how-would-you-represent-eof-in-bash

EOF http://forums.devshed.com/other-programming-languages-139/what-does-eof-do-328074.html


Linux documentation project / Advanced bash scripting

EN: http://tldp.org/LDP/abs/html/

FR: http://abs.traduc.org/abs-fr/