タブを区切り文字として使用し、空白を保持しながらbashの文字列を変数に解析する方法は?

タブを区切り文字として使用し、空白を保持しながらbashの文字列を変数に解析する方法は?

私はMySQLデータベースのいくつかの統計を含むさまざまな統計を表示するためのbashスクリプトを書いています。問題のある関連コードは次のとおりです。

read min max rows <<< $(mysql $dbDatabase -u $dbUser -p$dbPass -B -N -e \
    "SELECT MIN(\`DateTime\`), MAX(\`DateTime\`), COUNT(*) FROM $dbTable")
echo "Min Date:" $min
echo "Max Date:" $max
echo "Total Rows:" $rows

実行結果は次のとおりです。

Min Date: 2013-03-18
Max Date: 20:30:00
Total Rows: 2014-07-31 14:30:00 11225139

これは明らかに私が望むものではありません(日付/時間値が分割されています)。

Googleによると、$IFS私の質問に答える必要があります。残念ながら、まだ結果を正しく解析できません。

IFS=$'\t' read min max rows <<< ...

結果:

Min Date: 2013-03-18 20:30:00 2014-07-31 14:30:00 11225139
Max Date:
Total Rows:

msyql -B | tr $'\t' 'X'フィールドがタブで区切られていることを視覚的に証明するので、これは奇妙であることがわかりました。

回避策として、次の操作を実行して目的の出力を生成できます。

read min max rows <<< $(mysql $dbDatabase -u $dbUser -p$dbPass -B -N -e \
    "SELECT MIN(\`DateTime\`), MAX(\`DateTime\`), COUNT(*) FROM $dbTable" \
    | tr ' ' '.')
min=$(tr '.' ' ' <<< $min)
max=$(tr '.' ' ' <<< $max)

echo "Min Date:" $min
echo "Max Date:" $max
echo "Total Rows:" $rows

しかし、これはエレガントに見えず、「Unix方式」とは見えません。

私が間違っているのか、なぜ$IFS動作しないのか、きれいで(ハッキングされていない)理解しやすいコードを持つ正しい使い方が何であるかを知っている人はいますか?

ベストアンサー1

コマンド置換の結果の周りに引用符が必要です。"$(command)"たとえば(クエリをシミュレートする場合echo)。

$ IFS=$'\t' read min max rows <<< "$(echo -e "Wed Jul 30 15:40:38 EDT 2014\tThu Jul 31 15:40:38 EDT 2014\t27")"
$ echo "$min"; echo "$max"
Wed Jul 30 15:40:38 EDT 2014
Thu Jul 31 15:40:38 EDT 2014

または(より直接的に)使用プロセスの交換代わりに

$ IFS=$'\t' read min max rows < <(echo -e "Wed Jul 30 15:40:38 EDT 2014\tThu Jul 31 15:40:38 EDT 2014\t27")
$ echo "$min"; echo "$max"
Wed Jul 30 15:40:38 EDT 2014
Thu Jul 31 15:40:38 EDT 2014

おすすめ記事