¿Cómo capturo un conjunto de resultados de MySQL en una matriz bash?

¿Cómo capturo un conjunto de resultados de MySQL en una matriz bash?

Estoy usando bash shell en CentOS 7. Quiero ejecutar una consulta MySQL desde un script de shell e iterar sobre cada fila de resultados. Si se devolvieran 4 filas, pensé que podría capturar las cuatro filas en una matriz como esta:

query="select p.id, p.ebook_id, es.id FROM ...";
echo "$query" > /tmp/query.sql
mysql -u user --password=pass db_id < /tmp/query.sql > /tmp/query.csv

linesIN=`cat /tmp/query.csv | sed 's/\t/,/g'`
arraylength=${#linesIN[@]}
echo $arraylength

Sin embargo, $arraylengthsiempre genera resultados 1aunque puedo ver varias filas de resultados devueltas. ¿Cómo puedo modificar lo anterior para crear correctamente una matriz de resultados donde cada elemento de la matriz represente una fila del conjunto de resultados?

Respuesta1

Con el--batchopción, mysqldebería generar el resultado en un registro por línea y columnas separadas por tabulaciones. Puedes leer las líneas de una matriz confiestamapfiley sustitución de procesos, o sustitución de comandos y asignación de matrices:

mapfile results  < <( mysql --batch ... < query.sql )

o

set -f        # disable globbing
IFS=$'\n'     # set field separator to NL (only)
results=( $(mysql --batch ... ) )

(Tenga en cuenta que IFSdespués de esto permanece modificado y deshabilitado).

Luego, si desea dividir las columnas de una fila en algunas variables:

IFS=$'\t' read -r col1 col2 col2 ... <<< "${results[0]}"

tu tarea

linesIN=`cat /tmp/query.csv | sed 's/\t/,/g'`

no es unasignación de matriz(le falta el paréntesis). Simplemente asigna la salida de la sustitución del comando a una variable de cadena normal. (Cualquier nueva línea se incrustará allí, pero seguirá siendo una sola cadena). ${#linesIN[@]}Todavía funciona ya que en Bash/ksh las matrices de un solo elemento y las variables escalares actúan de la misma manera.

Respuesta2

Otra forma de hacerlo sería canalizar la salida del comando a un bucle while. Tenga en cuenta que desea incluir -N o que los resultados incluyan el nombre de la columna.

#!/bin/bash
#Script to read output from a mysql command line by line 

mysql -uroot -p example -N -e "select column from table" | while IFS= read -r loop
do
    echo "$loop"
done 

Y si solo desea un recuento, haría select count(columnName)e imprimiría los resultados.

Respuesta3

Si desea que la cantidad de líneas en un archivo sea igual a la cantidad de filas devueltas por la consulta, simplemente use wcpara contar la cantidad de líneas en el archivo.

  arraylength=$( wc -l < /tmp/query.csv)
  echo $arraylength

información relacionada