web-dev-qa-db-ja.com

MySQL結果セットをbash配列にキャプチャするにはどうすればよいですか?

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行を表す結果の配列を正しく作成するにはどうすればよいですか?

10
Dave

とともに - --batchオプションmysqlは、結果を1行に1レコード、列をタブで区切って出力する必要があります。 Bashの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では単一要素配列とスカラー変数が同じように機能するため、引き続き機能します。

11
ilkkachu

これを行う別の方法は、コマンドの出力を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
Joe M

ファイルの行数が必要な場合は、クエリから返される行数と同じになります。wcを使用して、ファイルの行数をカウントします

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