¿Cómo puedo leer la entrada del usuario como una matriz en Bash?


15

¿Cómo podría leer la entrada del usuario como una matriz en el bashshell?


¿Supongo que quieres leer de stdin? Mi respuesta también funcionará con ejecución como cat war_and_peace.txt | ./array_test.sh.
Stefano Palazzo

O simplemente ./array_test.sh < war_and_peace.txt.
Eliah Kagan

Respuestas:


14

Aquí hay una forma de hacerlo:

while read line
do
    my_array=("${my_array[@]}" $line)
done

echo ${my_array[@]}

Si solo lo ejecuta, seguirá leyendo desde la entrada estándar hasta que presione Ctrl + D (EOF). Luego, las líneas que ingresaste estarán en my_array. Algunos pueden encontrar este código confuso. El cuerpo del bucle básicamente dice my_array = my_array + element.

Algunas piezas de documentación interesantes:


3
read -res bastante útil / importante a veces ... El enlace de Stefano a la "página de manual integrada de lectura" explica su propósito ... (para evitar la interpretación de la barra invertida).
Peter.O

10

Léalo usando esto:

read -a arr

Y para imprimir, use:

for elem in ${arr[@]}
do 
  echo $elem
done

4

Y uno que no recrea la matriz cada vez (aunque requiere bash 3.1 o más reciente):

array=()
while IFS= read -r -p "Next item (end with an empty line): " line; do
    [[ $line ]] || break  # break if line is empty
    array+=("$line")
done

printf '%s\n' "Items read:"
printf '  «%s»\n' "${array[@]}"

Ver http://mywiki.wooledge.org/BashFAQ/001 para más información.

Y como siempre, para evitar escribir errores, lea http://mywiki.wooledge.org/BashGuide y evite las guías tldp como la guía avanzada de secuencias de comandos bash.


Buenos enlaces ... Gracias por señalar el IFSproblema. Sin anularlo, 'leer' borra todos los espacios en blanco iniciales y finales ... y, por supuesto, -rtambién ...
Peter.O

0

¿Qué tal este one-liner;)

arr=( $(cat -) )
echo ${arr[@]}

Editar:

en bash,

arr=(val1 val2 ...)

es la forma de asignar a una matriz . Al usarlo junto con la sustitución de comandos, puede leer en matrices de la tubería que no es posible usar readpara lograr esto de una manera directa:

echo -e "a\nb" | read -a arr
echo ${arr[@]}

Encontrará que no genera nada debido al hecho de que readno hace nada cuandostdin trata de una tubería, ya que una tubería puede ejecutarse en una subshell para que la variable no sea utilizable en absoluto.

Usando la forma sugerida por esta respuesta:

arr=(`echo -e "a\nb"`)
echo ${arr[@]}

Proporciona a bcuál es la forma más simple y directa que cualquier solución alternativa dada por las respuestas de los valores de lectura en una variable de shell desde una tubería y en bash read después de que una tubería no está estableciendo valores .


lo probaste?
cmak.fr

@ cmak.fr sí, funciona para mí
Quark

@Melebius He adjuntado una explicación y la ventaja de esta frase.
JiaHao Xu
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.