Traiter des listes correctement en Bash

25/03/2009

Bien souvent j’utilise des fonctions de boucle en Bash pour traiter des fichiers ou faire des tests. Vous pouvez utiliser une liste que vous donnez manuellement, une liste de fichier ou carrément utiliser une commande qui génère la liste.

Restons dans la simplicité, voici un ou deux exemples: ``

for i in “foo bar baz”

do echo $i done > affiche:

foo

bar

baz

#for i in find ./ -name "*.php" do cp $i ~/sauvegarde_php sed -i “s/\r//g” $i
done > copie chaque fichier php dans un répertoire de sauvegarde > puis remplace “\r” dans chaque fichier trouvé

#for i in cat monfichier.txt do grep $i autrefichier.txt || echo “$i not found !” done > à chaque ligne trouvé dans monfichier.txt > je vérifie si elle existe aussi dans autrefichier.txt > sinon j’affiche le souci ``

Là où on peut avoir un souci, c’est justement dans le dernier exemple. Imaginons que monfichier.txt contienne:

foo
bar
baz

et le script: #for i in `cat monfichier.txt` do echo $i done Dans ce cas, on retrouve bien une ligne pour chaque élément.

Mais un problème intervient dans ce cas:

une ligne à chercher
une autre ligne
la dernière ligne

Le résultat va être:

une
ligne
à
chercher
une
autre
ligne
la
dernière
ligne

Stupeur… tremblements… ce n’est pas une erreur mais le fonctionnement normal du principe de liste en Bash. En effet, la séparation des éléments se fait via des retours chariots **ou** des espaces…

Voici comment vous pouvez vous en sortir: utiliser la commande “read” qui attend bien un retour chariot (ou \n) pour passer à la suite: cat monfichier.txt | while read i do echo $i done Et on retrouve notre liste sans coupure à chaque espace mais bien pour chaque ligne.

Efficace non ?

Ça peut vous intéresser aussi


Sauvegarde automatisé en Bash

On m’a demandé hier soir sur un canal IRC ...


Manipuler les chaines en Bash

Je continue ma série d’articles sur le scripting bash....


Pool de thread en bash

Créer un pool de thread est une opération toujours un ...


Netcat, créez votre serveur en BASH

Bash est puissant, très puissant. Les commandes et utilisations sont vastes ...

Merci de m'aider à financer mes services

Si vous avez apprécié cet article, je vous serai reconnaissant de m'aider à me payer une petite bière :)

Si vous voulez en savoir plus sur l'utilisation de flattr sur mon blog, lisez cette page: Ayez pitié de moi

Commentaires

Ajouter un commentaire

Xate - 08/04/2009

Argh ! Un pipe ! Quel horreur. Je propose plutôt :

while read ligne; do echo $ligne done < monfichier.txt

C’est plus joli, non ?

Sinon, on peut aussi jouer en modifiant IFS, mais c’est moins portable…

Ajouter un commentaire

(*) Votre e-mail ne sera ni revendu, ni rendu public, ni utilisé pour vous proposer des mails commerciaux. Il n'est utilisé que pour vous contacter en cas de souci avec le contenu du commentaire, ou pour vous prévenir d'un nouveau commentaire si vous avez coché la case prévue à cet effet.