pimp mac instalar bash while-loop zsh expansion

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".