Leer líneas de un archivo en una matriz Bash [duplicado]

Resuelto Homunculus Reticulli asked hace 12 años • 6 respuestas

Estoy intentando leer un archivo que contiene líneas en una matriz Bash.

He probado lo siguiente hasta ahora:

Intento1

a=( $( cat /path/to/filename ) )

Intento2

index=0
while read line ; do
    MYARRAY[$index]="$line"
    index=$(($index+1))
done < /path/to/filename

Ambos intentos solo devuelven una matriz de un elemento que contiene la primera línea del archivo. ¿Qué estoy haciendo mal?

Estoy ejecutando bash 4.1.5

Homunculus Reticulli avatar Jul 09 '12 18:07 Homunculus Reticulli
Aceptado

El readarraycomando (también escrito mapfile) se introdujo en bash 4.0.

readarray -t a < /path/to/filename
chepner avatar Jul 09 '2012 12:07 chepner

Última revisión basada en el comentario de BinaryZebra y probada aquí . La adición de command evalpermite que la expresión se mantenga en el entorno de ejecución actual, mientras que las expresiones anteriores solo se mantienen durante la evaluación.

Utilice $IFS que no tenga espacios\pestañas, solo nuevas líneas/CR

$ IFS=$'\r\n' GLOBIGNORE='*' command eval  'XYZ=($(cat /etc/passwd))'
$ echo "${XYZ[5]}"
sync:x:5:0:sync:/sbin:/bin/sync

También tenga en cuenta que puede estar configurando la matriz correctamente pero leyéndola mal; asegúrese de usar comillas dobles ""y llaves {}como en el ejemplo anterior.


Editar:

Tenga en cuenta las muchas advertencias sobre mi respuesta en los comentarios sobre una posible expansión global, específicamente los comentarios de gniourf-gniourf sobre mis intentos anteriores de solucionarlo.

Con todas esas advertencias en mente, todavía dejo esta respuesta aquí (sí, bash 4 ha estado disponible durante muchos años, pero recuerdo que algunas Mac de solo 2/3 años tienen pre-4 como shell predeterminado)

Otras notas:

También puede seguir la sugerencia de Drizzt a continuación y reemplazar una subcapa bifurcada + gato con

$(</etc/passwd)

La otra opción que uso a veces es simplemente configurar IFS en XIFS y luego restaurarlo. Vea también la respuesta de Sorpigal , que no necesita preocuparse por esto.

nhed avatar Jul 09 '2012 11:07 nhed

La forma más sencilla de leer cada línea de un archivo en una bashmatriz es esta:

IFS=$'\n' read -d '' -r -a lines < /etc/passwd

Ahora simplemente indexe la matriz linespara recuperar cada línea, por ejemplo

printf "line 1: %s\n" "${lines[0]}"
printf "line 5: %s\n" "${lines[4]}"

# all lines
echo "${lines[@]}"
sorpigal avatar Jul 09 '2012 11:07 sorpigal