2008-09-17 7 views

Respuesta

45

bash (a diferencia de sh POSIX) soporta arrays:

fruits=(apple orange kiwi "dried mango") 
for fruit in "${fruits[@]}"; do 
    echo "${fruit}" 
done 

Esto tiene la ventaja de que elementos de la matriz pueden contener espacios u otros miembros de $ IFS; siempre que se inserten correctamente como elementos separados, se leen de la misma manera.

+0

También estoy viendo impresiones "secas" y "de mango" aquí, usando bash en Debian y Mac OS X. Así que esto no parece protegerme contra el IFS. :-( – emk

+0

emk, eso está mal - Estaba probando en zsh, no en bash; lo solucioné desde. –

+0

Puedo confirmar que esto funciona. – emk

4
 
for i in apple orange kiwi 
do 
    echo $i 
done 
+0

'echo" $ i "' dentro del ciclo - sin las comillas, esto hace la expansión global y la división de IFS en los elementos, haciendo que 'foo bar' sea igual a' foo bar' y que haga '* .txt' echo todos los archivos coincidentes en el directorio actual en lugar de emitir un literal '* .txt'. –

11

De esta manera:

FRUITS="apple orange kiwi" 
for FRUIT in $FRUITS; do 
    echo $FRUIT 
done 

Aviso esto no funcionará si hay espacios en los nombres de sus frutos. En ese caso, vea this answer, que es ligeramente menos portátil pero mucho más robusto.

+0

En Bash en Mac OS X, parece que necesito un punto y coma o un salto de línea antes del 'do'. – emk

+0

Sí, necesitas el punto y coma a menos que tu "do" esté en una nueva línea. Además, $ IFS debe contener un espacio para que esto funcione. –

+0

dependiendo de IFS durante la iteración (en lugar de simplemente la asignación) es mal juju, por lo que esta respuesta no es óptima. Por supuesto, la mía también: estaba probando en zsh, arreglado para bash desde entonces. –

6

Ahora que la respuesta que me gusta ha sido aceptada como la respuesta correcta, ahora pasaré a otro tema: cómo usar IFS para beneficio personal. :-P

fruits="apple,orange,kiwifruit,dried mango" 
(IFS=, 
for fruit in $fruits; do 
    echo "$fruit" 
done) 

He puesto el código entre corchetes para que el cambio IFS está aislado en su propio subproceso; por lo tanto, al final de la sección entre corchetes, IFS se revierte a su valor anterior. :-)

+0

Cuando intento 'fruits = (manzana naranja" kiwi fruit ")', bash divide "kiwi" y "fruit" en entidades separadas durante el ciclo. Mientras usted for/in, se quemará por el IFS. Pero 'echo $ {fruits [2]}' hace lo correcto, lo cual es bueno. – emk

+0

Consulte http://stackoverflow.com/questions/78592/what-is-a-good-equivalent-to-perl-lists-in-bash#78631 para obtener una versión de este código que funciona. – emk

+0

¡Gracias por tu opinión! Fijo. –

Cuestiones relacionadas