Como faço para capturar um conjunto de resultados do MySQL em uma matriz bash?

Como faço para capturar um conjunto de resultados do MySQL em uma matriz bash?

Estou usando o shell bash no CentOS 7. Quero executar uma consulta MySQL a partir de um script de shell e iterar em cada linha de resultados. Se houvesse 4 linhas retornadas, pensei que poderia capturar as quatro linhas em uma matriz assim:

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

No entanto, $arraylengthsempre gera saída, 1mesmo que eu possa ver várias linhas de resultados retornadas. Como posso modificar o acima para criar corretamente uma matriz de resultados onde cada elemento da matriz representa uma linha do conjunto de resultados?

Responder1

Com o--batchopção, mysqldeve gerar o resultado com um registro em uma linha e colunas separadas por tabulações. Você pode ler as linhas de um array comBashmapfilee substituição de processo ou substituição de comando e atribuição de array:

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

ou

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

(Observe que IFSpermanece modificado e globbing desativado depois disso.)

Então, se você quiser dividir as colunas de uma linha em algumas variáveis:

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

Sua tarefa

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

não é umatribuição de matriz(falta o parêntese). Ele apenas atribui a saída da substituição do comando a uma variável de string regular. (Qualquer nova linha será incorporada lá, mas ainda será uma única string.) ${#linesIN[@]}ainda funciona, pois em Bash/ksh matrizes de elemento único e variáveis ​​escalares agem da mesma forma.

Responder2

Outra maneira de fazer isso seria canalizar a saída do comando para um loop while. Observe que você deseja incluir -N ou os resultados incluem o nome da coluna.

#!/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 

E se você quiser apenas uma contagem, faça uma contagem select count(columnName)e imprima os resultados.

Responder3

Se você quiser o número de linhas em um arquivo, que será igual ao número de linhas retornadas da consulta, basta usar wcpara contar o número de linhas no arquivo

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

informação relacionada