是否有一种简单的方法可以从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

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


当前回答

本页上的许多答案都很薄弱,因为它们没有处理CSV格式中可能发生的一般情况。例如,字段中嵌入的逗号和引号,以及其他总是最终出现的条件。我们需要一个适用于所有有效CSV输入数据的通用解决方案。

这里有一个简单而强大的Python解决方案:

#!/usr/bin/env python

import csv
import sys

tab_in = csv.reader(sys.stdin, dialect=csv.excel_tab)
comma_out = csv.writer(sys.stdout, dialect=csv.excel)

for row in tab_in:
    comma_out.writerow(row)

命名为tab2csv文件,把它放在你的路径上,给它执行权限,然后像这样使用它:

mysql OTHER_OPTIONS --batch --execute='select * from whatever;' | tab2csv > outfile.csv

Python CSV-处理函数涵盖了CSV输入格式的大小写。

这可以通过流方法进行改进,以处理非常大的文件。

其他回答

不完全是CSV格式,但是MySQL客户端的tee命令可以用来将输出保存到本地文件中:

tee foobar.txt
SELECT foo FROM bar;

你可以使用notee禁用它。

SELECT…INTO OUTFILE…的问题;它需要在服务器上写文件的权限。

本页上的许多答案都很薄弱,因为它们没有处理CSV格式中可能发生的一般情况。例如,字段中嵌入的逗号和引号,以及其他总是最终出现的条件。我们需要一个适用于所有有效CSV输入数据的通用解决方案。

这里有一个简单而强大的Python解决方案:

#!/usr/bin/env python

import csv
import sys

tab_in = csv.reader(sys.stdin, dialect=csv.excel_tab)
comma_out = csv.writer(sys.stdout, dialect=csv.excel)

for row in tab_in:
    comma_out.writerow(row)

命名为tab2csv文件,把它放在你的路径上,给它执行权限,然后像这样使用它:

mysql OTHER_OPTIONS --batch --execute='select * from whatever;' | tab2csv > outfile.csv

Python CSV-处理函数涵盖了CSV输入格式的大小写。

这可以通过流方法进行改进,以处理非常大的文件。

mysql——batch, -B 打印结果,使用制表符作为列分隔符,每行在 新行。使用这个选项,mysql不使用历史文件。 批处理模式导致非表格输出格式和转义 特殊字符。转义可以通过使用原始模式禁用;看到 ——raw选项的描述。

这将为您提供一个制表符分隔的文件。由于逗号(或包含逗号的字符串)没有转义,因此将分隔符更改为逗号并不简单。

这里有一个相当粗糙的方法[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

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

到目前为止,除了MySQL Workbench之外,所有的解决方案都是不正确的,而且很可能对MySQL数据库中的某些内容不安全(即安全问题)。

MySQL Workbench(以及类似的phpMyAdmin)提供了一个正式的正确解决方案,但它们是为将输出下载到用户的位置而设计的。它们对于自动化数据导出之类的事情不是很有用。

这是不可能产生可靠的正确的CSV内容从mysql -B -e 'SELECT…'因为它不能编码回车符和字段中的空白。mysql的'-s'标志确实做反斜杠转义,并可能导致一个正确的解决方案。但是,使用脚本语言(具有良好的内部数据结构的语言,而不是Bash)和已经仔细解决编码问题的库要安全得多。

我想过为此写一个脚本,但当我想到我该怎么称呼它时,我突然想到要搜索同名的已有作品。虽然我还没有彻底讨论它,但mysql2csv看起来很有前途。不过,根据应用程序的不同,使用YAML方法指定SQL命令可能有吸引力,也可能没有吸引力。我对Ruby的最新版本的要求也不感兴趣,因为我的Ubuntu 12.04 (Precise穿山甲)笔记本电脑或Debian 6.0 (Squeeze)服务器都是标准版本。是的,我知道我可以使用RVM,但是我宁愿不为了这样一个简单的目的而维护RVM。