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

5

Estou usando o shell bash no CentOS 7. Eu quero executar uma consulta MySQL a partir de um script shell e iterar sobre cada linha de resultados. Se houvesse 4 linhas retornadas, pensei em capturar as quatro linhas em uma matriz da seguinte forma:

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, $arraylength sempre gera 1 , embora eu possa ver várias linhas de resultado retornadas. Como posso modificar o acima para criar corretamente uma matriz de resultados em que cada elemento na matriz representa uma linha do conjunto de resultados?

    
por Dave 29.05.2018 / 19:25

3 respostas

8

Com a --batch opção , mysql deve produzir o resultado um registro em uma linha e colunas separadas por tabulações. Você pode ler as linhas em uma matriz com % de coilde% e substituição de processos ou substituição de comandos e atribuição de matriz:

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

ou

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

(Observe que mapfile permanece modificado e globbing desativado após isso.)

Então, se você quiser dividir as colunas de uma linha para 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 é uma atribuição de matriz (falta o parêntese). Apenas atribui a saída da substituição de comandos a uma variável de string regular. (Todas as novas linhas serão incorporadas lá, mas ainda assim será uma única string.) IFS ainda funciona desde que em matrizes de um único elemento Bash / ksh e variáveis escalares agem da mesma forma.

    
por 29.05.2018 / 19:47
1

Outra maneira de fazer isso seria canalizar a saída do comando para um loop while. Observe que você deseja incluir o -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, você deve fazer um select count(columnName) e imprimir os resultados.

    
por 29.05.2018 / 20:35
1

Se você quiser o número de linhas em um arquivo, que será igual ao número de linhas retornadas da consulta, use apenas wc para contar o número de linhas no arquivo

  arraylength=$( wc -l < /tmp/query.csv)
  echo $arraylength
    
por 29.05.2018 / 19:46