
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, $arraylength
siempre genera resultados 1
aunque 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--batch
opción, mysql
debería generar el resultado en un registro por línea y columnas separadas por tabulaciones. Puedes leer las líneas de una matriz confiestamapfile
y 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 IFS
despué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 wc
para contar la cantidad de líneas en el archivo.
arraylength=$( wc -l < /tmp/query.csv)
echo $arraylength