Imprimir elementos de matriz en líneas separadas en Bash?


229

¿Cómo imprimo el elemento de matriz de una matriz Bash en líneas separadas? Este funciona, pero seguramente hay una mejor manera:

$ my_array=(one two three)
$ for i in ${my_array[@]}; do echo $i; done
one
two
three

Probé este pero no funcionó:

$ IFS=$'\n' echo ${my_array[*]}
one two three

Respuestas:


436

Intenta hacer esto:

$ printf '%s\n' "${my_array[@]}"

La diferencia entre $@y $*:

  • Sin citar, los resultados no están especificados. En Bash, ambos se expanden para separar args y luego se dividen y engloban.

  • Citado, "$@"expande cada elemento como un argumento separado, mientras que se "$*" expande a los argumentos combinados en un argumento: "$1c$2c..."(donde ces el primer carácter de IFS).

Casi siempre quieres "$@". Lo mismo vale para "${arr[@]}".

¡Cítalos siempre!


55
Y tenga en cuenta que las comillas dobles alrededor de la referencia de la variable son importantes si desea asegurarse de que los elementos con espacios internos no se dividan inadvertidamente.
danfuzz

44
@sputnick: no funciona, los elementos de la matriz terminan en una sola línea
Axel Bregnsbo

1
¿Para qué son los dos guiones después del comando? No encontré ninguna referencia a él en el manual.
joanpau

3
¿Hay alguna manera de hacerlo para que no muestre líneas en blanco si no hay elementos en la matriz sin tener que hacerlo | grep -v '^$'?
Noel Yap

2
@espaciomore '% s \ n' es el formato para la salida de la función printf. % s significa un marcador de posición para un argumento de cadena (en este caso, el elemento de matriz) y \ n agrega un salto de línea después de eso. Por lo tanto, habrá una cadena y un salto de línea en la salida para cada elemento de la matriz.
Koja

71

Solo cita el argumento para hacer eco:

( IFS=$'\n'; echo "${my_array[*]}" )

el sub shell ayuda a restaurar el IFS después de su uso


3
lo siento perreal, moví mi marca de verificación a sputnick, a pesar de que su solución me gustó mejor, solo porque aprendí sobre la función 'printf'.
Axel Bregnsbo

3
Gracias por esta respuesta, ¡me gusta! Las asignaciones son muy malas después de la expansión, por lo IFS=$'\n' echo "${my_array[*]}"que no funciona. ¡Oh bien!
cxw

@cxw, ¿qué quieres decir con "asignaciones suceden"?
Steven Shaw

1
@bschlueter, probé con Bash 4 - 4.4.23 (1) -release - ¡y funciona!
Steven Shaw

1
@cxw Ah, no vi lo que intentabas hacer allí. Creo que no funciona porque echoestá integrado en Bash. Sin embargo, puede envolverlo en una función y funcionará. gist.github.com/steshaw/53ba0095bce8ccab52d26a14375dedb8
Steven Shaw

40

Utilizando para :

for each in "${alpha[@]}"
do
  echo "$each"
done

Usando la historia ; tenga en cuenta que esto fallará si sus valores contienen !:

history -p "${alpha[@]}"

Usando basename ; tenga en cuenta que esto fallará si sus valores contienen /:

basename -a "${alpha[@]}"

Usando shuf ; tenga en cuenta que los resultados pueden no aparecer en orden:

shuf -e "${alpha[@]}"

19
"shuf" ... "podría no salir en orden" ... hilarante.
Walf

44
para shuf. ¿Quién hubiera pensado usar eso?
fbicknel

3

Intenté las respuestas aquí en un gigante para ... if loop, pero no tuve ninguna alegría, así que lo hice así, tal vez desordenado pero hice el trabajo:

 # EXP_LIST2 is iterated    
 # imagine a for loop
     EXP_LIST="List item"    
     EXP_LIST2="$EXP_LIST2 \n $EXP_LIST"
 done 
 echo -e $EXP_LIST2

aunque eso agregó un espacio a la lista, lo cual está bien, quería un poco sangrado. También suponga que "\ n" podría imprimirse en el original $ EP_LIST.


55
No parece un ejemplo completo.
kenorb

3

Otra variante útil es canalizar a tr:

echo "${my_array[@]}" | tr ' ' '\n'

Esto se ve simple y compacto


11
Excepto que esto se rompemy_array=( "one two" three )
Mike Holt

Se corrigió con comillas dobles.
Steven Shaw

No funcionó como se anuncia en la versión Bash 4+, tuve que usarlo echo "${my_array[@]}" | tr '' ' \n', aunque personalmente evitaría usarlo echoasí, donde trcreo que algo así tr '' ' \n' <<<"${my_array[@]}"podría ser un poco más fácil de leer más tarde.
S0AndS0
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.