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