kAworu's avatar

the Shellnigme

publié par kAworu
il y a plus de trois ans

Pour les amoureux du shell (sh POSIX) "traditionel" voilà une petite énigme interessante:

Comment faire une boucle sur les lignes d'une variable ?

par exemple, si je fais

myvar="`cat /etc/fstab`"

j'ai maintenant le contenu du fichier /etc/fstab dans $myvar. Comment boucler pour traiter le contenu ligne par ligne ?

for

Avec un for, on est obligé de modifier IFS (http://fr.wikipedia.org/wiki/Internal_Field_Separator) pour ne boucler ligne par ligne:

IFS='
'
for line in $myvar; do ... done

Mais attention, IFS à été modifié et cela peut influencer le reste du code (le corps de la boucle, et la suite). Il faut donc être très prudent et remettre la valeur par défaut de l'IFS juste après:

DEFAULT_IFS="$IFS"
IFS='
'
for line in $myvar; do
  IFS="$DEFAULT_IFS"
  ...
done

while

Avec la boucle while, il y a une solution simple:

echo "$myvar" | while read line; do ... done

Le problème, c'est que le while est dans un sous-shell, et que donc toute variable modifiée dans la boucle n'est disponible que dans le sous-shell:

$ i=0
$ cat /etc/fstab|while read l; do i=$((i + 1)); echo $i; done
1
2
3
4
$ echo $i
0

On pense donc à la forme:

while read line; do
...
done < fichier

qui a l'avantage de ne pas créer de sous processus. Avec les shells qui disposent de la substitution de processus, on peut écrire:

while read line; do
...
done < <(echo "$myvar")

C'est la manière élégante de créer un fichier temporaire. et voiçi finalement une version sans substitution de processus:

while read line; do
...
done <<EOF
`echo "$myvar"`
EOF
aucun commentaire

écrire un commentaire

écrire un commentaire:


(utilisé pour gravatar, ne sera pas affiché)



tu peux utiliser la syntaxe markdown :)