Comment puis-je modifier le code suivant de sorte que lorsqu'il est exécuté dans zsh, il développe $things
et l'itère l'un après l'autre?
things="one two"
for one_thing in $things; do
echo $one_thing
done
Je veux que la sortie soit:
one
two
Mais comme écrit ci-dessus, il génère:
one two
(Je recherche le comportement que vous obtenez lorsque vous exécutez le code ci-dessus dans bash)
Pour voir le comportement compatible avec Bourne Shell, vous devez définir l'option SH_Word_SPLIT
:
setopt shwordsplit # this can be unset by saying: unsetopt shwordsplit
things="one two"
for one_thing in $things; do
echo $one_thing
done
produirait:
one
two
Cependant, il est recommandé d’utiliser un tableau pour produire le fractionnement de Word, par exemple,
things=(one two)
for one_thing in $things; do
echo $one_thing
done
Vous voudrez peut-être aussi vous référer à:
3.1: Pourquoi $ var où var = "foo bar" ne fait-il pas ce que j'attends?
Vous pouvez utiliser l'indicateur d'expansion de variable z
pour effectuer le fractionnement de Word sur une variable.
things="one two"
for one_thing in ${(z)things}; do
echo $one_thing
done
En savoir plus sur cela et sur les autres indicateurs de variable dans man zshexpn
, sous "Indicateurs d'expansion de paramètres"
Vous pouvez supposer que le séparateur de champ interne (IFS) sur bash est\x20 (espace). Cela rend le travail suivant:
#IFS=$'\x20'
#things=(one two) #array
things="one two" #string version
for thing in ${things[@]}
do
echo $thing
done
En gardant cela à l'esprit, vous pouvez implémenter cela de différentes façons en manipulant simplement l'IFS; même sur des chaînes multi-lignes.
Une autre façon, qui est également portable entre les obus Bourne (sh, bash, zsh, etc.):
things="one two"
for one_thing in $(echo $things); do
echo $one_thing
done
Ou, si vous n'avez pas besoin de $things
défini en tant que variable:
for one_thing in one two; do
echo $one_thing
done
Utiliser for x in y z
donnera instruction au shell de parcourir une liste de mots, y, z
.
Le premier exemple utilise commande substitution pour transformer la chaîne "one two"
en une liste de mots, one two
(sans guillemets).
Le deuxième exemple est la même chose sans echo
.
Voici un exemple qui ne fonctionne pas, pour mieux le comprendre:
for one_thing in "one two"; do
echo $one_thing
done
Remarquez les citations. Cela va simplement imprimer
one two
parce que les guillemets signifient que la liste ne contient qu'un seul élément, one two
.