bash - mac - Cómo iterar a través de la cadena de una palabra a la vez en zsh
uninstall zsh mac (4)
¿Cómo modifico el siguiente código para que cuando se ejecute en zsh expanda $things
e itere a través de ellas una a la vez?
things="one two"
for one_thing in $things; do
echo $one_thing
done
Quiero que la salida sea:
one
two
Pero como está escrito arriba, produce:
one two
(Estoy buscando el comportamiento que obtienes al ejecutar el código anterior en bash)
Otra forma, que también es portátil entre shells Bourne (sh, bash, zsh, etc.):
things="one two"
for one_thing in $(echo $things); do
echo $one_thing
done
O, si no necesita $things
definidas como una variable:
for one_thing in one two; do
echo $one_thing
done
Usar for x in yz
indicará al shell que pase por una lista de palabras, y, z
.
El primer ejemplo utiliza la sustitución de comandos para transformar la cadena "one two"
en una lista de palabras, one two
(sin comillas).
El segundo ejemplo es lo mismo sin echo
.
Aquí hay un ejemplo que no funciona, para entenderlo mejor:
for one_thing in "one two"; do
echo $one_thing
done
Note las citas. Esto simplemente se imprimirá
one two
porque las comillas significan que la lista tiene un solo elemento, one two
.
Para ver el comportamiento compatible con el shell Bourne, deberías configurar la opción 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
produciría
one
two
Sin embargo, se recomienda usar una matriz para producir división de palabras, por ejemplo,
things=(one two)
for one_thing in $things; do
echo $one_thing
done
También puede referirse a:
3.1: ¿Por qué $ var donde var = "foo bar" no hace lo que espero?
Puede asumir que el Separador de campo interno (IFS) en bash es / x20 (espacio). Esto hace que el siguiente trabajo:
#IFS=$''/x20''
#things=(one two) #array
things="one two" #string version
for thing in ${things[@]}
do
echo $thing
done
Con esto en mente, puede implementar esto de muchas maneras diferentes simplemente manipulando el IFS; incluso en cadenas multilínea.
Puede usar el indicador de expansión de la variable z
para dividir palabras en una variable
things="one two"
for one_thing in ${(z)things}; do
echo $one_thing
done
Lea más sobre esta y otras banderas variables en man zshexpn
, en "Parámetros de expansión de parámetros".