读取具有多个列和空格的MySQL结果集

时间:2017-04-20 17:12:06

标签: mysql bash

假装我有一个MySQL表test,如下所示:

+----+---------------------+
| id |     value           |
+----+---------------------+
| 1  | Hello World         |
| 2  | Foo Bar             |
| 3  | Goodbye Cruel World |
+----+---------------------+

我执行查询SELECT id, value FROM test。 如何使用read

将每列分配给Bash中的变量

read -a截断value中第一个空格后的所有内容:

mysql -D "jimmy" -NBe "SELECT id, value FROM test" | while read -a row;
do
    id="${row[0]}"
    value="${row[1]}"

    echo "$id : $value"
done;

,输出如下:

1 : Hello
2 : Foo
3 : Goodbye

但我需要它看起来像:

1 : Hello World
2 : Foo Bar
3 : Goodbye Cruel World

我知道有些args我可以传递给MySQL来格式化表格格式的结果,但我需要解析每一行中的每个值。这只是我的问题的简化示例。

2 个答案:

答案 0 :(得分:5)

使用read loop中的单个字段代替数组:

mysql -D "jimmy" -NBe "SELECT id, value FROM test" | while read -r id value;
do
    echo "$id : $value"
done

这将确保将id读入id字段,其他所有内容都会被读入value字段 - read当输入的字段数多于读入的变量数时,表现为行为。如果要读取的列数更多,则使用不与实际数据冲突的分隔符(例如@)会有所帮助:

mysql -D "jimmy" -NBe "SELECT CONCAT(id, '@', value, '@', column3) FROM test" | while IFS='@' read -r id value column3;
do
    echo "$id : $value : $column3"
done

答案 1 :(得分:1)

您可以这样做,也可以避免将命令传递给while循环,以避免创建子shell。

while read -r line; do
    id=$(echo $line | awk '{print $1}')
    value=$(echo $line | awk '{print $1=""; print $0}'|sed ':a;N;$!ba;s/\n/ /g'| sed 's/^[ \t]*//g')
    echo "ID: $id"
    echo "VALUE: $value"
done< <(mysql -D "jimmy" -NBe "SELECT id, value FROM test")

如果要将所有ID和值存储在数组中供以后使用,可以将其修改为如下所示。

#!/bin/bash

declare -A -g arr

while read -r line; do
    id=$(echo $line | awk '{print $1}')
    value=$(echo $line | awk '{print $1=""; print $0}'|sed ':a;N;$!ba;s/\n/ /g'| sed 's/^[ \t]*//g')

    arr[$id]=$value
done< <(mysql -D "jimmy" -NBe "SELECT id, value FROM test")

for key in "${!arr[@]}"; do
    echo "$key: ${arr[$key]}"
done

为您提供此输出

dumbledore@ansible1a [OPS]:~/tmp/tmp > bash test.sh
1: Hello World
2: Foo Bar
3: Goodbye Cruel World