web-dev-qa-db-fra.com

Comment capturer un jeu de résultats MySQL dans un tableau bash?

J'utilise bash Shell sur CentOS 7. Je veux exécuter une requête MySQL à partir d'un script Shell et parcourir chaque ligne de résultats. S'il y avait 4 lignes retournées, je pensais pouvoir capturer les quatre lignes dans un tableau comme ceci:

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

Cependant, $arraylength sort toujours 1 même si je peux voir plusieurs lignes de résultat renvoyées. Comment puis-je modifier ce qui précède pour créer correctement un tableau de résultats où chaque élément du tableau représente une ligne de l'ensemble de résultats?

10
Dave

Avec le --batch option , mysql devrait afficher le résultat un enregistrement sur une ligne et des colonnes séparées par des tabulations. Vous pouvez lire les lignes d'un tableau avec mapfile de Bash et la substitution de processus, ou la substitution de commande et l'affectation de tableau:

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

ou

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

(Notez que IFS reste modifié et la globalisation désactivée après cela.)

Ensuite, si vous souhaitez diviser les colonnes d'une ligne en quelques variables:

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

Votre affectation

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

n'est pas une affectation de tableau (il manque la parenthèse). Il affecte simplement la sortie de la substitution de commande à une variable de chaîne régulière. (Tous les retours à la ligne y seront intégrés, mais ce sera toujours une seule chaîne.) ${#linesIN[@]} fonctionne toujours car dans les tableaux à élément unique Bash/ksh et les variables scalaires agissent de la même manière.

11
ilkkachu

Une autre façon de le faire serait de diriger la sortie de la commande vers une boucle while. Notez que vous souhaitez inclure le -N ou les résultats incluent le nom de la colonne.

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

Et si vous voulez juste un décompte, vous feriez une select count(columnName) et imprimeriez les résultats.

3
Joe M

Si vous voulez le nombre de lignes dans un fichier, qui sera égal au nombre de lignes renvoyées par la requête, utilisez simplement wc pour compter le nombre de lignes dans le fichier

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