
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 $arraylength
immer 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--batch
Möglichkeit, mysql
sollte das Ergebnis als Datensatz pro Zeile und durch Tabulatoren getrennte Spalten ausgeben. Sie können die Zeilen in ein Array einlesen mitBashsmapfile
und 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 IFS
die Ä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 wc
Zählen der Zeilen in der Datei
arraylength=$( wc -l < /tmp/query.csv)
echo $arraylength