OVH Cloud OVH Cloud

[for] fonctionnalité zsh à reproduire sous bsh

11 réponses
Avatar
David LE BOURGEOIS
Bonjour.

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 :-).

David.

1 réponse

1 2
Avatar
Stephane CHAZELAS
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:

array=(1 "" "3 4")
print -l $array
# renverrait comme print -l "${array[@]}":
# 1
#
# 3 4
#
# et:
print -l ${array:#}
# renverrait:
# 1
# 3 4

--
Stéphane


1 2