1347

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

引用符で囲む必要がある列がたくさんある場合、またはエスケープする必要がある結果に引用符がある場合は、面倒です。

4

40 に答える 40

1935

[ MySQL クエリ結果をテキストまたは CSV ファイルに保存]から:

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 では。

このコマンドを使用すると、列名はエ​​クスポートされません。

また、 MySQL を実行しているサーバー/var/lib/mysql-files/orders.csv上にあることに注意してください。MySQL プロセスを実行しているユーザーは、選択したディレクトリへの書き込み権限を持っている必要があります。権限がない場合、コマンドは失敗します。

リモート サーバー (特に、 HerokuAmazon RDSなどのホストまたは仮想化されたマシン) からローカル マシンに出力を書き込みたい場合、このソリューションは適していません。

于 2008-12-10T16:07:55.443 に答える
525
mysql your_database --password=foo < my_requests.sql > out.csv

タブ区切りです。そのようにパイプして、真の CSV を取得します (ユーザーJohn Carterに感謝します):

... .sql | sed 's/\t/,/g' > out.csv
于 2010-04-08T16:53:24.607 に答える
227

mysql --バッチ、-B

タブを列区切りとして使用し、各行を新しい行にして結果を出力します。このオプションを使用すると、mysql は履歴ファイルを使用しません。バッチ モードでは、非表形式の出力形式と特殊文字のエスケープが行われます。raw モードを使用すると、エスケープを無効にすることができます。--raw オプションの説明を参照してください。

これにより、タブ区切りのファイルが作成されます。コンマ (またはコンマを含む文字列) はエスケープされないため、区切り文字をコンマに変更するのは簡単ではありません。

于 2009-09-30T10:51:27.487 に答える
173

これはかなり危険な方法です[1] :

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

それはかなりうまくいきます。もう一度言いますが、正規表現は書き込み専用です。


正規表現の説明:

  • s/// は、最初の // の間にあるものを 2 番目の間にあるもので置き換えることを意味します //
  • 最後の「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

[1] どこかで見つけたのですが、信用できません。

于 2011-03-22T17:31:58.460 に答える
114

「tr」を介してパイプします (Unix/ Cygwinのみ):

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

注意: これは埋め込まれたカンマも埋め込まれたタブも処理しません。

于 2012-10-11T15:19:41.340 に答える
71

これで数回救われました。それは速く、それはうまくいきます!

--batch タブを列区切りとして使用し、各行を新しい行として結果を印刷します。

--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 に変換することもできます(ただし、タブがフィールド値内にある可能性があるため注意してください (テキスト フィールドなど))。

tr '\t' ',' < file.tsv > file.csv

于 2016-01-29T13:52:47.823 に答える
42

Paul Tomblinによって提供されたOUTFILE ソリューションでは、ファイルが MySQL サーバー自体に書き込まれるため、これはFILEアクセス、ログイン アクセス、またはそのボックスからファイルを取得するためのその他の手段を持っている場合にのみ機能します。

そのようなアクセス権がなく、タブ区切りの出力が CSV の合理的な代替手段である場合 (たとえば、最終目標が Excel にインポートすることである場合)、serbaut のソリューション(mysql --batchおよび オプションでを使用--raw) が最適です。

于 2010-06-22T13:48:00.397 に答える
41

MySQL WorkbenchはレコードセットをCSVにエクスポートでき、フィールドのコンマを非常にうまく処理しているようです。CSVはOpenOfficeCalc で正常に開きます。

于 2012-06-26T17:15:54.913 に答える
34

使用する:

mysql your_database -p < my_requests.sql | awk '{print $1","$2}' > out.csv
于 2011-11-10T18:41:05.193 に答える
27

コマンドラインから、これを行うことができます:

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*

クレジット: Amazon RDS から CSV ファイルへのテーブルのエクスポート

于 2015-06-25T06:50:02.497 に答える
14

これは簡単で、バッチ モードや出力ファイルを必要とせずに何でも動作します。

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

from your_table where etc;

説明:

  1. "各フィールドでに置き換え""ます -->replace(field1, '"', '""')
  2. 各結果を引用符で囲みます -->concat('"', result1, '"')
  3. 引用された各結果の間にコンマを置く -->concat_ws(',', quoted1, quoted2, ...)

それでおしまい!

于 2011-12-06T18:50:13.263 に答える
11

CSVエンジンを使用するMySQLテーブルを作成できます。

次に、ハードディスク上にファイルが作成されます。このファイルは常にCSV形式であり、処理せずにコピーすることができます。

于 2008-12-10T23:34:58.460 に答える
8

これが私がすることです:

echo $QUERY | \
  mysql -B  $MYSQL_OPTS | \
  perl -F"\t" -lane 'print join ",", map {s/"/""/g; /^[\d.]+$/ ? $_ : qq("$_")} @F ' | \
  mail -s 'report' person@address

Perlスクリプト(他の場所から抜粋)は、タブ間隔のフィールドをCSVに変換するという素晴らしい仕事をします。

于 2011-07-07T17:34:02.467 に答える
8

user7610に基づいて構築すると、これが最善の方法です。mysql outfileファイルの所有権と上書きの問題が 60 分間ありました。

クールではありませんが、5分で機能しました。

php csvdump.php localhost root password database tablename > whatever-you-like.csv

<?php

$server = $argv[1];
$user = $argv[2];
$password = $argv[3];
$db = $argv[4];
$table = $argv[5];

mysql_connect($server, $user, $password) or die(mysql_error());
mysql_select_db($db) or die(mysql_error());

// fetch the data
$rows = mysql_query('SELECT * FROM ' . $table);
$rows || die(mysql_error());


// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');

// output the column headings

$fields = [];
for($i = 0; $i < mysql_num_fields($rows); $i++) {
    $field_info = mysql_fetch_field($rows, $i);
    $fields[] = $field_info->name;
}
fputcsv($output, $fields);

// loop over the rows, outputting them
while ($row = mysql_fetch_assoc($rows)) fputcsv($output, $row);

?>
于 2015-05-29T18:36:18.417 に答える
5

正確には CSV 形式ではありませんが、MySQLクライアントからのteeコマンドを使用して、出力をローカルファイルに保存できます。

tee foobar.txt
SELECT foo FROM bar;

を使用して無効にすることができますnotee

問題SELECT … INTO OUTFILE …;は、サーバーでファイルを書き込む許可が必要なことです。

于 2014-05-29T18:14:01.920 に答える
3

ヘッダー付きの標準形式の CSV ファイルを書き込み、データをストリームとして書き込む Python のシンプルなソリューション (メモリ使用量が少ない):

import csv

def export_table(connection, table_name, output_filename):
    cursor = connection.cursor()
    cursor.execute("SELECT * FROM " + table_name)

    # thanks to https://gist.github.com/madan712/f27ac3b703a541abbcd63871a4a56636 for this hint
    header = [descriptor[0] for descriptor in cursor.description]

    with open(output_filename, 'w') as csvfile:
        csv_writer = csv.writer(csvfile, dialect='excel')
        csv_writer.writerow(header)
        for row in cursor:
            csv_writer.writerow(row)

次のように使用できます。

import mysql.connector as mysql
# (or https://github.com/PyMySQL/PyMySQL should work but I haven't tested it)

db = mysql.connect(
    host="localhost",
    user="USERNAME",
    db="DATABASE_NAME",
    port=9999)

for table_name in ['table1', 'table2']:
    export_table(db, table_name, table_name + '.csv')

db.close()

簡単にするために、これには、資格情報などに環境変数を使用するなど、別の回答からのより手の込んだものは意図的に含まれcontextlibていません。

于 2021-08-03T16:07:48.227 に答える
3

サーバーに PHP がセットアップされている場合は、mysql2csvを使用して、任意の MySQL クエリの (実際には有効な) CSV ファイルをエクスポートできます。MySQL - SELECT * INTO OUTFILE LOCAL ? で私の回答を参照してください。もう少しコンテキスト/情報が必要です。

からのオプション名を維持しようとしたmysqlので、--fileおよび--queryオプションを提供するだけで十分です。

./mysql2csv --file="/tmp/result.csv" --query='SELECT 1 as foo, 2 as bar;' --user="username" --password="password"

「インストール」mysql2csv経由

wget https://gist.githubusercontent.com/paslandau/37bf787eab1b84fc7ae679d1823cf401/raw/29a48bb0a43f6750858e1ddec054d3552f3cbc45/mysql2csv -O mysql2csv -q && (sha256sum mysql2csv | cmp <(echo "b109535b29733bd596ecc8608e008732e617e97906f119c66dd7cf6ab2865a65  mysql2csv") || (echo "ERROR comparing hash, Found:" ;sha256sum mysql2csv) ) && chmod +x mysql2csv

(Gistの内容をダウンロードし、チェックサムをチェックして実行可能にする。)

于 2018-05-16T10:19:23.233 に答える
2

その後のエラーが発生している場合はsecure-file-priv、宛先ファイルの場所をクエリ内でシフトしたC:\ProgramData\MySQL\MySQL Server 8.0\Uploads後も、クエリの後に -

SELECT * FROM attendance INTO OUTFILE 'C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\FileName.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';

は機能していません。\(backsplash) をクエリから/(forwardsplash)に変更するだけです。

そして、それはうまくいきます!!

例:

SELECT * FROM 出席 INTO OUTFILE 'C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/FileName.csv' フィールドは ',' で囲まれ、'"' で囲まれた行は '\n' で終了します。

成功したクエリを実行するたびに、毎回新しい CSV ファイルが生成されます。かっこいいでしょ?

于 2019-12-20T15:27:01.237 に答える
0

使用しているマシンに PHP がインストールされている場合は、それを行うための PHP スクリプトを作成できます。PHP インストールに MySQL 拡張機能がインストールされている必要があります。

次のように、コマンド ラインから PHP インタープリターを呼び出すことができます。

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

--php-iniMySQL 拡張機能を有効にする独自の PHP 構成を使用する必要がある場合があるため、スイッチを含めています。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 および text フィールドで問題がないことです。これらのフィールドは正しく引用符で囲まれ、それらの改行は CSV リーダーによって、レコード区切りではなくテキストの一部として解釈されます。これは、後でsedなどで修正するのが難しいものです。

于 2012-03-17T08:46:57.200 に答える
0

これは汚くて醜いです。これは、PHP-*-admin だけがあり、サーバーがオプションで実行されている特定の状況にのみ適しているため、クエリで句を--secure-file-priv使用することはできません。INTO OUTFILE '/path/to/export.csv'

できることは、CSV の行を ... wait for it!, で解析しCONCAT、結果をコピーしてファイルに貼り付けることです。

SQL形式が必要な例を次に示します(CSVに適応させるのは簡単です):

SELECT CONCAT(
"('",
`username`, "', '",
`password`, "', '",
`first_name`, "', '",
`last_name`, "', '",
`gender`, "'),"
) AS `row` 
FROM `users`
WHERE `role` != 'Not set'
AND `user_status` = 'Active'
ORDER BY `role`, `gender`, `user_id`
LIMIT 200

これにより、次のような適切なインポート出力が得られます。

('jane', '3d7ff...', 'Jane', 'Doe', 'Female'),  
('john', 'd2a33...', 'John', 'Doe', 'Male'),
...
于 2021-12-19T05:30:59.333 に答える
0

これは、出力をファイルに書き込む必要がなくexpat、インストールするだけで済み、値を適切にエスケープNULLし、null 値に対して (リテラルの代わりに) 空の文字列を出力します。

結果を XML 形式で出力するよう MySQL に指示し (--xmlフラグを使用)、以下の C プログラムを介して結果をパイプします。

これは、これを行うための最速の方法にかなり近いはずです。


// mysql-xml-to-csv.c

#include <assert.h>
#include <ctype.h>
#include <err.h>
#include <expat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/*
    Example of MySQL XML output:

    <?xml version="1.0"?>

    <resultset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" statement="SELECT id as IdNum, lastName, firstName FROM User">
        <row>
            <field name="IdNum">100040</field>
            <field name="lastName" xsi:nil="true"/>
            <field name="firsttName">Cher</field>
        </row>
    </resultset>
*/

#define BUFFER_SIZE     (1 << 16)

// These accumulate the first row column names and values until first row is entirely read (unless the "-N" flag is given)
static XML_Char **column_names;
static size_t num_column_names;
static XML_Char **first_row_values;
static size_t num_first_row_values;

// This accumulates one column's value
static XML_Char *elem_text;                     // note: not nul-terminated
static size_t elem_text_len;

// Flags
static int first_column;
static int reading_value;

// Expat callback functions
static void handle_elem_start(void *data, const XML_Char *el, const XML_Char **attr);
static void handle_elem_text(void *userData, const XML_Char *s, int len);
static void handle_elem_end(void *data, const XML_Char *el);

// Helper functions
static void output_csv_row(XML_Char **values, size_t num);
static void output_csv_text(const char *s, size_t len);
static void add_string(XML_Char ***arrayp, size_t *lengthp, const XML_Char *string, size_t len);
static void add_chars(XML_Char **strp, size_t *lenp, const XML_Char *string, size_t nchars);
static size_t xml_strlen(const XML_Char *string);
static void free_strings(XML_Char ***arrayp, size_t *lengthp);
static void usage(void);

int
main(int argc, char **argv)
{
    char buf[BUFFER_SIZE];
    int want_column_names = 1;
    XML_Parser p;
    FILE *fp;
    size_t r;
    int i;

    // Parse command line
    while ((i = getopt(argc, argv, "hN")) != -1) {
        switch (i) {
        case 'N':
            want_column_names = 0;
            break;
        case 'h':
            usage();
            exit(0);
        case '?':
        default:
            usage();
            exit(1);
        }
    }
    argv += optind;
    argc -= optind;
    switch (argc) {
    case 0:
        fp = stdin;
        break;
    case 1:
        if ((fp = fopen(argv[0], "r")) == NULL)
            err(1, "%s", argv[0]);
        break;
    default:
        usage();
        exit(1);
    }

    // Initialize arrays for column names and first row values
    if (want_column_names) {
        if ((column_names = malloc(10 * sizeof(*column_names))) == NULL)
            err(1, "malloc");
        if ((first_row_values = malloc(10 * sizeof(*first_row_values))) == NULL)
            err(1, "malloc");
    }

    // Initialize parser
    if ((p = XML_ParserCreate(NULL)) == NULL)
        errx(1, "can't initialize parser");
    XML_SetElementHandler(p, handle_elem_start, handle_elem_end);
    XML_SetCharacterDataHandler(p, handle_elem_text);

    // Process file
    while (1) {
        if ((r = fread(buf, 1, sizeof(buf), fp)) == 0 && ferror(fp))
            errx(1, "error reading input");
        if (XML_Parse(p, buf, r, r == 0) == XML_STATUS_ERROR)
            errx(1, "line %u: %s", (unsigned int)XML_GetCurrentLineNumber(p), XML_ErrorString(XML_GetErrorCode(p)));
        if (r == 0)
            break;
    }

    // Clean up
    XML_ParserFree(p);
    fclose(fp);

    // Done
    return 0;
}

static void
handle_elem_start(void *data, const XML_Char *name, const XML_Char **attr)
{
    if (strcmp(name, "row") == 0)
        first_column = 1;
    else if (strcmp(name, "field") == 0) {
        if (column_names != NULL) {
            while (*attr != NULL && strcmp(*attr, "name") != 0)
                attr += 2;
            if (*attr == NULL)
                errx(1, "\"field\" element is missing \"name\" attribute");
            add_string(&column_names, &num_column_names, attr[1], xml_strlen(attr[1]));
        } else {
            if (!first_column)
                putchar(',');
            putchar('"');
        }
        reading_value = 1;
    }
}

static void
handle_elem_text(void *userData, const XML_Char *s, int len)
{
    if (!reading_value)
        return;
    if (column_names != NULL)
        add_chars(&elem_text, &elem_text_len, s, len);
    else
        output_csv_text(s, len);
}

static void
handle_elem_end(void *data, const XML_Char *name)
{
    if (strcmp(name, "row") == 0) {
        if (column_names != NULL) {
            output_csv_row(column_names, num_column_names);
            output_csv_row(first_row_values, num_first_row_values);
            free_strings(&column_names, &num_column_names);
            free_strings(&first_row_values, &num_first_row_values);
        } else
            putchar('\n');
    } else if (strcmp(name, "field") == 0) {
        if (column_names != NULL) {
            add_string(&first_row_values, &num_first_row_values, elem_text, elem_text_len);
            free(elem_text);
            elem_text = NULL;
            elem_text_len = 0;
        } else
            putchar('"');
        first_column = 0;
        reading_value = 0;
    }
}

static void
output_csv_row(XML_Char **values, size_t num_columns)
{
    int i;

    for (i = 0; i < num_columns; i++) {
        if (i > 0)
            putchar(',');
        putchar('"');
        output_csv_text(values[i], xml_strlen(values[i]));
        putchar('"');
    }
    putchar('\n');
}

static void
output_csv_text(const XML_Char *s, size_t len)
{
    while (len-- > 0) {
        if (*s == '"')
            putchar('"');
        putchar(*s);
        s++;
    }
}

static void
add_string(XML_Char ***arrayp, size_t *lengthp, const XML_Char *string, size_t nchars)
{
    char **new_array;

    if ((new_array = realloc(*arrayp, (*lengthp + 1) * sizeof(**arrayp))) == NULL)
        err(1, "malloc");
    *arrayp = new_array;
    if (((*arrayp)[*lengthp] = malloc((nchars + 1) * sizeof(XML_Char))) == NULL)
        err(1, "malloc");
    memcpy((*arrayp)[*lengthp], string, nchars * sizeof(XML_Char));
    (*arrayp)[*lengthp][nchars] = (XML_Char)0;
    (*lengthp)++;
}

static void
add_chars(XML_Char **strp, size_t *lenp, const XML_Char *string, size_t nchars)
{
    XML_Char *new_array;

    if ((new_array = realloc(*strp, (*lenp + nchars) * sizeof(XML_Char))) == NULL)
        err(1, "malloc");
    *strp = new_array;
    memcpy(*strp + *lenp, string, nchars * sizeof(XML_Char));
    *lenp += nchars;
}

static size_t
xml_strlen(const XML_Char *string)
{
    size_t len;

    len = 0;
    while (string[len] != (XML_Char)0)
        len++;
    return len;
}

static void
free_strings(char ***arrayp, size_t *lengthp)
{
    while (*lengthp > 0)
        free((*arrayp)[--*lengthp]);
    free(*arrayp);
    *arrayp = NULL;
}

static void
usage(void)
{
    fprintf(stderr, "Usage: mysql-xml-to-csv [options] [file.xml]\n");
    fprintf(stderr, "Options:\n");
    fprintf(stderr, "  -N\tDo not output column names as the first row\n");
    fprintf(stderr, "  -h\tShow this usage info\n");
}

C をあまり頻繁に使用しない場合は、次のコードを実行してこのコードをビルドできます (expat ライブラリがインストールされていると仮定します)。

gcc mysql-xml-to-csv.c -lexpat -o mysql-xml-to-csv

openSUSE 15.2 および gcc 7.5.0 でテスト済み。

Update:githubでオープン ソース プロジェクトとして利用できるようになりました。

于 2021-04-08T16:00:16.997 に答える