
CentOS 7 で bash シェルを使用しています。シェル スクリプトから MySQL クエリを実行し、結果の各行を反復処理したいと考えています。返される行が 4 行の場合、次のように配列で 4 行をキャプチャできると考えました。
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
常に出力されます1
。配列内の各要素が結果セットの 1 行を表す結果の配列を正しく作成するには、上記をどのように変更すればよいでしょうか。
答え1
とともに--batch
オプションは、mysql
結果を1行に1レコード、列をタブで区切って出力します。行を配列に読み込むには、バッシュのmapfile
プロセス置換、またはコマンド置換と配列代入:
mapfile results < <( mysql --batch ... < query.sql )
または
set -f # disable globbing
IFS=$'\n' # set field separator to NL (only)
results=( $(mysql --batch ... ) )
(IFS
これ以降は変更されたままになり、グロブは無効になることに注意してください。)
次に、行の列をいくつかの変数に分割する場合:
IFS=$'\t' read -r col1 col2 col2 ... <<< "${results[0]}"
あなたの課題
linesIN=`cat /tmp/query.csv | sed 's/\t/,/g'`
ではない配列の割り当て(括弧がありません)。コマンド置換の出力を通常の文字列変数に割り当てるだけです。(改行はそこに埋め込まれますが、それでも単一の文字列になります。) ${#linesIN[@]}
Bash/ksh では単一要素配列とスカラー変数は同じように動作するので、それでも機能します。
答え2
別の方法としては、コマンドの出力を while ループにパイプする方法があります。-N を含めるか、結果に列名を含める必要があることに注意してください。
#!/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
カウントだけが必要な場合は、 を実行しselect count(columnName)
て結果を出力します。
答え3
ファイル内の行数(クエリから返される行数と同じ)が必要な場合は、wc
ファイル内の行数をカウントするために使用します。
arraylength=$( wc -l < /tmp/query.csv)
echo $arraylength