有没有一种简单的方式可以从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 order_id,product_name,qty
FROM orders
WHERE foo = 'bar'
INTO OUTFILE '/var/lib/mysql-files/orders.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';
注意:该语法可能需要重新排序
SELECT order_id,product_name,qty
INTO OUTFILE '/var/lib/mysql-files/orders.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM orders
WHERE foo = 'bar';
在MySQL的较新版本中,使用此命令将不导出列名。
另外请注意,/var/lib/mysql-files/orders.csv
将位于运行MySQL的服务器上。MySQL进程正在运行的用户必须具有写入所选目录的权限,否则该命令将失败。
如果您想要从远程服务器(特别是像Heroku或Amazon RDS等托管或虚拟化机器)将输出写入本地计算机,则此解决方案不适用。
mysql your_database --password=foo < my_requests.sql > out.tsv
... .sql | sed 's/\t/,/g' > out.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/'/\'/ 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
[1] 我在某个地方找到了这个内容,不能获得任何功劳。
(注:该段内容无关IT技术)--password
在命令执行后提示用户输入密码。wobble
是数据库名称,但我同意这不够清晰,已经进行了编辑以提高清晰度。谢谢。 - Tim Harding将其通过“tr”传输(仅限Unix/Cygwin):
mysql <database> -e "<query here>" | tr '\t' ',' > data.csv
--batch 使用tab作为列分隔符打印结果,每行一个新行。
--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
tr'\t','<'file.tsv'>'file.csv
OUTFILE解决方案由Paul Tomblin提供会在MySQL服务器上写入文件,因此只有在您具有FILE访问权限以及登录访问权限或其他检索该框中文件的手段时才有效。
如果您没有这样的访问权限,并且制表符分隔的输出是CSV的合理替代品(例如,如果您的最终目标是导入Excel),那么serbaut的解决方案(使用mysql --batch
并可选地使用--raw
)是正确的方法。
MySQL Workbench 可以导出记录集到 CSV 文件,并且它似乎可以很好地处理字段中的逗号。CSV 文件可以在 OpenOffice Calc 中正常打开。
mysql -B -e 'SELECT ...'
的输出中可靠地生成正确的CSV内容是不可能的,因为它无法对字段中的换行符和空格进行编码。mysql
的'-s'标志确实进行了反斜杠转义,并可能导致正确的解决方案。然而,使用脚本语言(具有良好的内部数据结构,而不是Bash),以及已经仔细解决了编码问题的库会更加安全。mysql -B
的输出无法修复。 - mc0e这个页面上很多回答都比较薄弱,因为它们不能处理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输入格式情况。
可以通过流式处理方法来改进,使其能够处理超大文件。
REPLACE()
函数来转义引号。 - dsm