Imprimir una matriz en un archivo con cada elemento de la matriz en una nueva línea en bash

13

Estoy probando el contenido de una matriz en un archivo con cada elemento de la matriz en una nueva línea en el archivo.

IFS=$'\n'   
echo "${mtches[@]}" > sample1.txt 


El contenido de mtches es "qwe" y "asd". Pero el sample1.txtarchivo contiene qwe asden una sola línea. ¿Por qué no está tomando el valor IFS en la imagen?

Ashwin
fuente

Respuestas:

17

Usted debe utilizar printfen lugar deecho :

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

Si mtchesestá vacío, todavía se generaría una línea vacía. Para dar cuenta de eso:

{ [ "${#mtches[@]}" -eq 0 ] || printf '%s\n' "${mtches[@]}"; } > file

En bash(y también shells POSIX), a menudo usa la matriz de Parámetros Posicionales como en "$@"lugar de "$*", a menos que tenga una razón especial. Eso también es cierto en los shells que admiten matrices regulares, desde man bash - sección Arrays :

Se puede hacer referencia a cualquier elemento de una matriz usando $ {name [subíndice]}. Las llaves son necesarias para evitar conflictos con los operadores de expansión de nombre de archivo del shell. Si el subíndice es '@' o '*', la palabra se expande a todos los miembros del nombre de la matriz. Estos subíndices difieren solo cuando la palabra aparece entre comillas dobles. Si la palabra está entre comillas dobles, $ {name [*]} se expande a una sola palabra con el valor de cada miembro de la matriz separado por el primer carácter de la variable IFS, y $ {name [@]} expande cada elemento de nombre a una palabra separada. Cuando no hay miembros de la matriz, $ {name [@]} se expande a nada. Si la expansión entre comillas dobles ocurre dentro de una palabra, la expansión del primer parámetro se une con la parte inicial de la palabra original, y la expansión del último parámetro se une con la última parte de la palabra original.

Úselo solo "${array[*]}"cuando desee unir todos los elementos de la matriz a una cadena.

Cuonglm
fuente
¿Cómo hace eso una diferencia?
Ashwin
7

Quieres usar ${mtches[*]}en su lugar.

Cuando lo use "${mtches[@]}", no importa cuál sea el valor de $IFS, bash dividirá la matriz en múltiples argumentos. Lo que quiere es un argumento único con cada elemento de matriz unido por \n. ${mtches[*]}logra esto.

También como una forma temporal de configuración $IFS, puede hacer:

( IFS=$'\n'; echo "${mtches[*]}" > sample1.txt )

Entonces no tiene que molestarse en volver a configurarlo.

Patricio
fuente
pubs.opengroup.org/onlinepubs/9699919799/utilities/… <- referencia POSIX (esto no se aplica solo a bash).
Mat
O use printf...
jasonwryan
2

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[@]}"
Steven Penny
fuente