Wie erfasse ich einen MySQL-Ergebnissatz in einem Bash-Array?

Wie erfasse ich einen MySQL-Ergebnissatz in einem Bash-Array?

Ich verwende die Bash-Shell unter CentOS 7. Ich möchte eine MySQL-Abfrage aus einem Shell-Skript ausführen und jede Ergebniszeile durchlaufen. Wenn 4 Zeilen zurückgegeben werden, 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

Es wird jedoch $arraylengthimmer ausgegeben 1, obwohl ich mehrere zurückgegebene Ergebniszeilen sehe. Wie kann ich das Obige ändern, um korrekt ein Ergebnisarray zu erstellen, in dem jedes Element im Array eine Zeile aus dem Ergebnissatz darstellt?

Antwort1

Mit dem--batchMöglichkeit, mysqlsollte das Ergebnis als Datensatz pro Zeile und durch Tabulatoren getrennte Spalten ausgeben. Sie können die Zeilen in ein Array einlesen mitBashsmapfileund Prozesssubstitution bzw. Befehlssubstitution und Arrayzuweisung:

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 IFSdie Änderungen bestehen bleiben und Globbing danach deaktiviert ist.)

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 keinArray-Zuweisung(es fehlt die Klammer). Es weist die Ausgabe der Befehlsersetzung einfach einer regulären Zeichenfolgenvariable zu. (Alle Zeilenumbrüche werden dort eingebettet, aber es bleibt eine einzelne Zeichenfolge.) ${#linesIN[@]}funktioniert immer noch, da sich in Bash/ksh Einzelelement-Arrays und Skalarvariablen gleich verhalten.

Antwort2

Eine andere Möglichkeit wäre, die Ausgabe des Befehls an eine While-Schleife weiterzuleiten. Beachten Sie, dass Sie -N einschließen müssen, da die Ergebnisse sonst den Spaltennamen enthalten.

#!/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 eine Zählung wünschen, führen Sie ein durch select count(columnName)und drucken die Ergebnisse aus.

Antwort3

Wenn Sie die Anzahl der Zeilen in einer Datei benötigen, die der Anzahl der von der Abfrage zurückgegebenen Zeilen entspricht, verwenden Sie einfach die Funktion zum wcZählen der Zeilen in der Datei

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

verwandte Informationen