Bash
如何使用製表符作為分隔符將 bash 中的字元串解析為變數並保留空格?
我正在編寫一個 bash 腳本來顯示各種統計數據,其中一些來自 MySQL 數據庫。我遇到困難的相關程式碼是:
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
這顯然不是我想要的(DateTime 值已被拆分)
根據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
不適合我,正確的用法是擁有乾淨(非hacky)和可理解的程式碼?
您需要在命令替換的結果周圍加上引號,即
"$(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