Je suis confronté à un petit soucis concernant les espaces dans une
boucle for. Je m'explique :
david@abeille ~/tmp $ echo $SHELL
/bin/zsh
david@abeille ~/tmp $ a="1 2 3"
david@abeille ~/tmp $ for i in $a ; do echo "[$i]" ; done
[1 2 3]
david@abeille ~/tmp $ /bin/sh
sh-2.04$ a="1 2 3"
sh-2.04$ for i in $a ; do echo "[$i]" ; done
[1]
[2]
[3]
Comment puis-je reproduire cette interprétation correcte de zsh dans sh
(ou ksh) ?
Je suis en fait face au problème des noms de fichiers contenant des
espaces. Et même en protégeant l'espace par un \, l'interprétation reste
la même. J'ai aussi essayé avec les quotes, mais sans succès.
Par exemple :
$ fichiers="
f1
fichier n2
'fichier numéro 3'
"
Merci de répondre à cette question un peu triviale, mais là je sèche :-).
Le Tue, 30 Sep 2003 19:06:04 +0200, David LE BOURGEOIS écrivait :
for i in "$a"; do printf '%sn' "[$i]"; done
Au poil, merci.
À noter toutefois que dans zsh
for i in "$a"; do printf '%sn' "[$i]"; done et for i in $a; do printf '%sn' "[$i]"; done
Ne sont pas équivalent dans le cas ou $a est indéfinie ou vide.
De meme,
dans
array=(1 "" "3 4") for i in $array; do printf '%sn' "[$i]"; done for i in "$array[@]"; do printf '%sn' "[$i]"; done
ne sont pas équivalents ($array est en fait équivalent à "${array[@]:#}"
Cela tient probablement au fait que les arrays de zsh ne sont pas "à trous" comme dans les autres shells. Si je fais: a[5]=a a[100]=b j'obtiens un array à 100 elements où les elements de 1 à 4 et de 6 à 99 sont vides (alors qu'avec bash c'est un array à 2 elements [impossible à dupliquer d'ailleurs, b=("${a[@]}") n'est pas une copie de "a", les indices ne sont pas les memes]). $a est la liste des éléments non-vides de "a", "$a[@]" est l'exacte définition de "a". C'est plus cohérent dans la mesure où zsh a les "associative arrays":
typeset -A h1 h2 h1[5]=a h2[100]=b Ça me fait un hash à deux elements que je peux copier par: h2=(${(kv)h1}) # kv = keys + values
Mais ça fait que finalement, dans beaucoup de cas, en zsh aussi, on va etre obligé de mettre des "" autour des variables et d'utiliser "$a[@]" au lieu de $a pour etre rigoureux. Il est important de le savoir.
À mon avis, pour une fois, le choix des auteurs de zsh est discutable, là-dessus. Ce filtre implicite des valeurs vides aurait pu etre évité sachant que zsh permet de spécifier explicitement des filtres. On aurait pu avoir:
Le Tue, 30 Sep 2003 19:06:04 +0200, David LE BOURGEOIS <david.lebourgeois-nospam@free.fr> écrivait :
for i in "$a"; do printf '%sn' "[$i]"; done
Au poil, merci.
À noter toutefois que dans zsh
for i in "$a"; do printf '%sn' "[$i]"; done
et
for i in $a; do printf '%sn' "[$i]"; done
Ne sont pas équivalent dans le cas ou $a est indéfinie ou vide.
De meme,
dans
array=(1 "" "3 4")
for i in $array; do printf '%sn' "[$i]"; done
for i in "$array[@]"; do printf '%sn' "[$i]"; done
ne sont pas équivalents ($array est en fait équivalent à
"${array[@]:#}"
Cela tient probablement au fait que les arrays de zsh ne sont
pas "à trous" comme dans les autres shells. Si je fais:
a[5]=a
a[100]=b
j'obtiens un array à 100 elements où les elements de 1 à 4 et de
6 à 99 sont vides (alors qu'avec bash c'est un array à 2
elements [impossible à dupliquer d'ailleurs, b=("${a[@]}")
n'est pas une copie de "a", les indices ne sont pas les memes]).
$a est la liste des éléments non-vides de "a", "$a[@]" est
l'exacte définition de "a".
C'est plus cohérent dans la mesure où zsh a les "associative
arrays":
typeset -A h1 h2
h1[5]=a
h2[100]=b
Ça me fait un hash à deux elements que je peux copier par:
h2=(${(kv)h1}) # kv = keys + values
Mais ça fait que finalement, dans beaucoup de cas, en zsh aussi,
on va etre obligé de mettre des "" autour des variables et
d'utiliser "$a[@]" au lieu de $a pour etre rigoureux. Il est
important de le savoir.
À mon avis, pour une fois, le choix des auteurs de zsh est
discutable, là-dessus. Ce filtre implicite des valeurs vides
aurait pu etre évité sachant que zsh permet de spécifier
explicitement des filtres. On aurait pu avoir:
Le Tue, 30 Sep 2003 19:06:04 +0200, David LE BOURGEOIS écrivait :
for i in "$a"; do printf '%sn' "[$i]"; done
Au poil, merci.
À noter toutefois que dans zsh
for i in "$a"; do printf '%sn' "[$i]"; done et for i in $a; do printf '%sn' "[$i]"; done
Ne sont pas équivalent dans le cas ou $a est indéfinie ou vide.
De meme,
dans
array=(1 "" "3 4") for i in $array; do printf '%sn' "[$i]"; done for i in "$array[@]"; do printf '%sn' "[$i]"; done
ne sont pas équivalents ($array est en fait équivalent à "${array[@]:#}"
Cela tient probablement au fait que les arrays de zsh ne sont pas "à trous" comme dans les autres shells. Si je fais: a[5]=a a[100]=b j'obtiens un array à 100 elements où les elements de 1 à 4 et de 6 à 99 sont vides (alors qu'avec bash c'est un array à 2 elements [impossible à dupliquer d'ailleurs, b=("${a[@]}") n'est pas une copie de "a", les indices ne sont pas les memes]). $a est la liste des éléments non-vides de "a", "$a[@]" est l'exacte définition de "a". C'est plus cohérent dans la mesure où zsh a les "associative arrays":
typeset -A h1 h2 h1[5]=a h2[100]=b Ça me fait un hash à deux elements que je peux copier par: h2=(${(kv)h1}) # kv = keys + values
Mais ça fait que finalement, dans beaucoup de cas, en zsh aussi, on va etre obligé de mettre des "" autour des variables et d'utiliser "$a[@]" au lieu de $a pour etre rigoureux. Il est important de le savoir.
À mon avis, pour une fois, le choix des auteurs de zsh est discutable, là-dessus. Ce filtre implicite des valeurs vides aurait pu etre évité sachant que zsh permet de spécifier explicitement des filtres. On aurait pu avoir: