it-swarm.com.de

Wie erfasse ich eine MySQL-Ergebnismenge in einem Bash-Array?

Ich verwende Bash Shell unter CentOS 7. Ich möchte eine MySQL-Abfrage über ein Shell-Skript ausführen und jede Ergebniszeile durchlaufen. Wenn 4 Zeilen zurückgegeben würden, dachte ich, ich könnte die vier Zeilen in einem Array wie folgt erfassen:

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

$arraylength Gibt jedoch immer 1 Aus, obwohl mehrere Ergebniszeilen zurückgegeben werden. Wie kann ich das oben Gesagte ändern, um ein Array von Ergebnissen korrekt zu erstellen, wobei jedes Element im Array eine Zeile aus der Ergebnismenge darstellt?

10
Dave

Mit dem --batch option , mysql sollte das Ergebnis einen Datensatz in einer Zeile und durch Tabulatoren getrennte Spalten ausgeben. Sie können die Zeilen zu einem Array mit Bashs mapfile lesen und die Substitution verarbeiten oder die Substitution und Befehlszuweisung befehlen:

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

oder

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

(Beachten Sie, dass IFS geändert bleibt und das Globbing danach deaktiviert wird.)

Wenn Sie dann die Spalten einer Zeile in einige Variablen aufteilen möchten:

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

Ihre Aufgabe

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

ist kein Array-Zuweisung (es fehlt die Klammer). Es wird lediglich die Ausgabe der Befehlssubstitution einer regulären Zeichenfolgenvariablen zugewiesen. (Alle Zeilenumbrüche werden dort eingebettet, es handelt sich jedoch weiterhin um eine einzelne Zeichenfolge.) ${#linesIN[@]} funktioniert immer noch, da in Bash/ksh Einzelelement-Arrays und skalare Variablen gleich funktionieren.

11
ilkkachu

Eine andere Möglichkeit wäre, die Ausgabe des Befehls an eine while-Schleife weiterzuleiten. Beachten Sie, dass Sie das -N oder die Ergebnisse den Spaltennamen enthalten möchten.

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

Und wenn Sie nur zählen möchten, führen Sie eine select count(columnName) aus und drucken die Ergebnisse aus.

3
Joe M

Wenn Sie möchten, dass die Anzahl der Zeilen in einer Datei der Anzahl der von der Abfrage zurückgegebenen Zeilen entspricht, verwenden Sie einfach wc, um die Anzahl der Zeilen in der Datei zu zählen

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