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

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


当前回答

如果您正在使用的机器上安装了PHP,则可以编写PHP脚本来完成该任务。它要求PHP安装已经安装了MySQL扩展。

你可以像这样从命令行调用PHP解释器:

php --php-ini path/to/php.ini your-script.php

我将包括——PHP -ini开关,因为您可能需要使用自己的PHP配置来启用MySQL扩展。在PHP 5.3.0+上,该扩展默认是启用的,因此不再需要使用配置来启用它。

然后,您可以像任何正常的PHP脚本一样编写导出脚本:

<?php
    #mysql_connect("localhost", "username", "password") or die(mysql_error());
    mysql_select_db("mydb") or die(mysql_error());

    $result = mysql_query("SELECT * FROM table_with_the_data p WHERE p.type = $typeiwant");

    $result || die(mysql_error());

    while($row = mysql_fetch_row($result)) {
      $comma = false;
      foreach ($row as $item) {

        # Make it comma separated
        if ($comma) {
          echo ',';
        } else {
          $comma = true;
        }

        # Quote the quotes
        $quoted = str_replace("\"", "\"\"", $item);

        # Quote the string
        echo "\"$quoted\"";
      }
        echo "\n";
    }
?>

这种方法的优点是,它对包含换行文本的varchar和文本字段没有任何问题。这些字段被正确地引用,其中的换行符将被CSV阅读器解释为文本的一部分,而不是记录分隔符。这在sed之后是很难纠正的。

其他回答

从你的命令行,你可以这样做:

mysql -h *hostname* -P *port number* --database=*database_name* -u *username* -p -e *your SQL query* | sed 's/\t/","/g;s/^/"/;s/$/"/;s/\n//g' > *output_file_name.csv*

Credits:将表从Amazon RDS导出到CSV文件

MySQL Workbench可以将记录集导出到CSV,而且它似乎可以很好地处理字段中的逗号。CSV可以在OpenOffice Calc中打开。

微小的Bash脚本,用于对CSV转储进行简单查询,灵感来自Tim Harding的回答。

#!/bin/bash

# $1 = query to execute
# $2 = outfile
# $3 = mysql database name
# $4 = mysql username

if [ -z "$1" ]; then
    echo "Query not given"
    exit 1
fi

if [ -z "$2" ]; then
    echo "Outfile not given"
    exit 1
fi

MYSQL_DB=""
MYSQL_USER="root"

if [ ! -z "$3" ]; then
    MYSQL_DB=$3
fi

if [ ! -z "$4" ]; then
    MYSQL_USER=$4
fi

if [ -z "$MYSQL_DB" ]; then
    echo "Database name not given"
    exit 1
fi

if [ -z "$MYSQL_USER" ]; then
    echo "Database user not given"
    exit 1
fi

mysql -u $MYSQL_USER -p -D $MYSQL_DB -B -s -e "$1" | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" > $2
echo "Written to $2"

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

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,…)

就是这样!

本页上的许多答案都很薄弱,因为它们没有处理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输入格式的大小写。

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