arrays - recorrer - Leer líneas de un archivo en una matriz Bash
variables en bash (6)
Esta pregunta ya tiene una respuesta aquí:
Estoy tratando de leer un archivo que contiene líneas en una matriz de Bash.
He intentado lo siguiente hasta ahora:
Intento1
a=( $( cat /path/to/filename ) )
Attempt2
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 corriendo bash 4.1.5
Última revisión basada en el comentario del comentario de BinaryZebra y probada aquí . La adición de command eval
permite que la expresión se mantenga en el presente entorno de ejecución, mientras que las expresiones anteriores solo se mantienen durante la evaluación.
Use $ 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 muy bien pero leyendo mal: asegúrese de usar las comillas dobles ""
y las llaves {}
como en el ejemplo anterior
Editar:
Tenga en cuenta las muchas advertencias sobre mi respuesta en comentarios sobre la posible expansión glob, específicamente los comentarios de gniourf-gniourf sobre mis intentos previos de evitarlo
Con todas esas advertencias en mente, sigo dejando esta respuesta aquí (sí, bash 4 ha estado fuera por muchos años, pero recuerdo que algunas macs de solo 2/3 años tienen pre-4 como shell por defecto)
Otras notas:
También puede seguir la sugerencia de drizzt a continuación y reemplazar un gato subshell + bifurcado con
$(</etc/passwd)
La otra opción que a veces uso es simplemente establecer IFS en XIFS, luego restaurar después. Ver también la respuesta de Sorpigal que no necesita molestarse con esto
La forma más simple de leer cada línea de un archivo en una matriz de bash
es esta:
IFS=$''/n'' read -d '''' -r -a lines < /etc/passwd
Ahora solo indexe las lines
la matriz para recuperar cada línea, por ejemplo
printf "line 1: %s/n" "${lines[0]}"
printf "line 5: %s/n" "${lines[4]}"
# all lines
echo "${lines[@]}"
Tu primer intento estuvo cerca. Aquí está el enfoque simplista usando su idea.
file="somefileondisk"
lines=`cat $file`
for line in $lines; do
echo "$line"
done
Una forma alternativa si el archivo contiene cadenas sin espacios con 1 cadena en cada línea:
fileItemString=$(cat filename |tr "/n" " ")
fileItemArray=($fileItemString)
Comprobar:
Imprimir toda la matriz:
${fileItemArray[*]}
Length=${#fileItemArray[@]}
El comando readarray
(también mapfile
deletreado) se introdujo en bash 4, creo.
readarray a < /path/to/filename
#!/bin/bash
IFS=$''/n'' read -d'''' -r -a inlines < testinput
IFS=$''/n'' read -d'''' -r -a outlines < testoutput
counter=0
cat testinput | while read line;
do
echo "$((${inlines[$counter]}-${outlines[$counter]}))"
counter=$(($counter+1))
done
# OR Do like this
counter=0
readarray a < testinput
readarray b < testoutput
cat testinput | while read myline;
do
echo value is: $((${a[$counter]}-${b[$counter]}))
counter=$(($counter+1))
done