是否有一种简单的方法可以从Linux命令行运行MySQL查询并以CSV格式输出结果?

以下是我现在正在做的:

mysql -u uid -ppwd -D dbname << EOQ | sed -e 's/        /,/g' | tee list.csv
select id, concat("\"",name,"\"") as name
from students
EOQ

当有很多列需要用引号括起来时,或者如果结果中有需要转义的引号,就会变得混乱。


当前回答

这很简单,它适用于任何不需要批处理模式或输出文件的东西:

select concat_ws(',',
    concat('"', replace(field1, '"', '""'), '"'),
    concat('"', replace(field2, '"', '""'), '"'),
    concat('"', replace(field3, '"', '""'), '"'))

from your_table where etc;

解释:

—> Replace (field1, ' ' ', ' ' ' ') 每个结果都用引号括起来——> concat('"', result1, '"') 在每个引用的结果之间使用逗号——> concat_ws(',', quoted1, quoted2,…)

就是这样!

其他回答

这救了我几次。它又快又有效!

——批 打印结果,使用制表符作为列分隔符,每行在 新行。 ——raw禁用字符转义(\n, \t, \0和\)

例子:

mysql -udemo_user -p -h127.0.0.1 --port=3306 \
   --default-character-set=utf8mb4 --database=demo_database \
   --batch --raw < /tmp/demo_sql_query.sql > /tmp/demo_csv_export.tsv

为了完整起见,您可以转换为CSV(但要小心,因为制表符可能位于字段值内部—例如,文本字段)

文件。tsv >文件

使用Tim Harding发布的解决方案,我创建了这个Bash脚本来促进这个过程(根密码是需要的,但你可以很容易地修改脚本来请求任何其他用户):

#!/bin/bash

if [ "$1" == "" ];then
    echo "Usage: $0 DATABASE TABLE [MYSQL EXTRA COMMANDS]"
    exit
fi

DBNAME=$1
TABLE=$2
FNAME=$1.$2.csv
MCOMM=$3

echo "MySQL password: "
stty -echo
read PASS
stty echo

mysql -uroot -p$PASS $MCOMM $DBNAME -B -e "SELECT * FROM $TABLE;" | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" > $FNAME

它将创建一个名为database.table.csv的文件

mysql your_database --password=foo < my_requests.sql > out.tsv

这将产生一个制表符分隔的格式。如果你确定逗号没有出现在任何列数据中(选项卡也没有),你可以使用这个管道命令来获得一个真正的CSV(感谢用户John Carter):

... .sql | sed 's/\t/,/g' > out.csv

这里有一个相当粗糙的方法[1]:

mysql --user=wibble --password mydatabasename -B -e "select * from vehicle_categories;" | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" > vehicle_categories.csv

它运行得很好。不过,正则表达式再次证明只能写。


正则表达式的解释:

S ///意味着用第二个//替换第一个//之间的内容 结尾的“g”是一个修饰语,意思是“所有实例,而不仅仅是第一个” ^(在这里)表示行开始 $(在这个上下文中)表示行结束

所以,把它们放在一起:

s/'/\'/          Replace ' with \'
s/\t/\",\"/g     Replace all \t (tab) with ","
s/^/\"/          at the beginning of the line place a "
s/$/\"/          At the end of the line, place a "
s/\n//g          Replace all \n (newline) with nothing

我是在什么地方捡到的,但这不是我的功劳。

通过'tr'管道(仅限Unix/Cygwin):

mysql <database> -e "<query here>" | tr '\t' ',' > data.csv

注意:这既不处理嵌入的逗号,也不处理嵌入的制表符。