74

コマンドラインでMySQLへのクエリの出力からヘッダーのないCSVデータを取得したい。このクエリはMySQLサーバーとは別のマシンで実行しているため、「INTOOUTFILE」を使用したGoogleの回答はすべて適切ではありません。

だから私は実行しmysql -e "select people, places from things"ます。これは、次のようなものを出力します。

+--------+-------------+
| people | places      |
+--------+-------------+
|   Bill | Raleigh, NC |
+--------+-------------+

まあ、それは良くありません。でもねえ、見て!何かにパイプするだけで、タブ区切りのリストになります。

people  places
Bill    Raleigh, NC

それはより良いです-少なくともそれはプログラムで解析可能です。しかし、TSV、CSV、およびそのヘッダーは必要ありません。でヘッダーを取り除くことはできますがmysql <stuff> | tail -n +2、MySQLにそれを省略するフラグがある場合は、それを避けたいのです。また、すべてのタブをカンマに置き換えることはできません。これは、カンマを含むコンテンツを処理しないためです。

では、MySQLでヘッダーを省略して、CSV形式のデータを取得するにはどうすればよいですか?

4

9 に答える 9

105

部分的な答えとして:mysql -N -B -e "select people, places from things"

-N列ヘッダーを印刷しないように指示します。-B「バッチモード」であり、タブを使用してフィールドを区切ります。

タブ区切りの値では不十分な場合は、このStackoverflow Q&Aを参照してください。

于 2013-05-16T16:33:22.703 に答える
18

上記の解決策は、特別な場合にのみ機能します。埋め込まれたコンマ、埋め込まれた引用符など、一般的なケースでCSVを困難にするあらゆる問題に直面します。

自分に有利に働き、一般的な解決策を使用してください。正しく実行すれば、二度と考える必要はありません。非常に強力なソリューションの1つは、csvkitコマンドラインユーティリティです。Pythonを介してすべてのオペレーティングシステムで利用できます。経由でインストールしpip install csvkitます。これにより、正しいCSVデータが得られます。

    mysql -e "select people, places from things" | csvcut -t

これにより、ヘッダーがそのままの状態でコンマ区切りのデータが生成されます。ヘッダー行を削除するには:

    mysql -e "select people, places from things" | csvcut -t | tail -n +2

これにより、OPが要求したものが生成されます。

于 2016-11-21T19:36:45.513 に答える
14

私はこれを処理するために独自のコマンドラインツールを作成することになりました。引用符で囲まれたフィールドなどを処理する方法を知っていることを除けば、と似てcutいます。このツールを@Jimothyの回答と組み合わせると、このコマンドを使用して、ファイルシステムにアクセスできないリモートのMySQLサーバーからヘッダーのないCSVを取得できます。 :

$ mysql -N -e "select people, places from things" | csvm -i '\t' -o ','
Bill,"Raleigh, NC"

githubのcsvmaster

于 2013-07-28T16:18:39.443 に答える
10

これは、追加の非標準ツールを使用せずに、クライアント側で結果をCSVに保存する方法です。この例では、 clientと。のみを使用してい ます。mysqlawk

1行:

mysql --skip-column-names --batch -e'select * from dump3' t | awk -F'\ t''{sep = ""; for(i = 1; i <= NF; i ++){gsub(/ \\ t /、 "\ t"、$ i); gsub(/ \\ n /、 "\ n"、$ i); gsub(/ \\\\ /、 "\\"、$ i); gsub(/ "/、" \ "\" "、$ i); printf sep" \ "" $ i "\" "; sep ="、 "; if(i == NF){printf" \ n "} }} '

何をする必要があるかについての論理的な説明

  1. まず、 RAWモード(オプション付き)でデータがどのように表示されるかを見てみましょう。データベースと--rawテーブルはそれぞれtdump3

    値に新しい行が配置されているため、「新しい行」(最初の行)から始まるフィールドが3行に分割されていることがわかります。

mysql --skip-column-names --batch --raw -e'select * from dump3' t

1行2行改行
引用符"バックスラッシュ\2つの引用符""2つのバックスラッシュ\\2つのタブ改行
フィールドの終わり

別の行1特別な文字を含まない別の行の説明
  1. バッチモードでの出力データ(オプションなし)-各レコードは、および--rawのような文字をエスケープすることによって1行のテキストに変更されます\ <tab>new-lines
mysql --skip-column-names --batch -e'select * from dump3' t

1行2行の改行\n引用符"バックスラッシュ\\2つの引用符""2つのバックスラッシュ\\\\2つのタブ\t\t改行\nフィールドの終わり
別の行1特別な文字を含まない別の行の説明
  1. そしてCSV形式でのデータ出力

手がかりは、エスケープ文字を使用してデータをCSV形式で保存することです。

これを行う方法は、(バックスラッシュおよび改行としてのタブとして)mysql --batch生成する特別なエンティティを各値(フィールド)の同等のバイトに変換することです。次に、値全体がでエスケープされ、。で囲まれます。ところで-エスケープと囲みに同じ文字を使用すると、2つの特殊文字がないため、出力と処理が簡単になります。このため、(csv形式の観点から)値に関係するのは、 whithin値に変更することだけです。より一般的な方法(それぞれエスケープと囲み、および)では、最初にに変更してから、に変更する必要があります。\t\\\n"""""\"\\\"\"

そして、コマンドの説明を段階的に説明します。

#ステップ2に示すように、1行の出力を生成します。
mysql --skip-column-names --batch -e'select * from dump3' t

#mysqlがそのように生成するため、フィールドセパレータをに設定します
| awk -F'\ t'

#これはmysqlデータからすべての行/レコードの反復を開始します-awkの標準的な動作
'{

#最初の出力フィールドの前にセパレーターを出力しないため、フィールドセパレーターは空です
sep = "";

-すべてのフィールドで反復し、フィールドをcsvの適切な値に変換します
for(i = 1; i <= NF; i ++){
--注:\\下の2つのスラッシュは、エスケープされているため、awkの場合は\を意味します

--\tを<tab>に対応するバイトに変更します
    gsub(/ \\ t /、 "\ t"、$ i);

--\nを改行に対応するバイトに変更します
    gsub(/ \\ n /、 "\ n"、$ i);

--2つの\\を1つの\に変更  
    gsub(/ \\\\ /、 "\\"、$ i);

-値を文字通りCSVに適切な値に変更します-「」を「」に変更します
    gsub(/ "/、" \ "\" "、$ i);

--「」で囲まれた出力フィールドを出力し、前にセパレータを追加します
    printf sep "\" "$ i" \ "";  

--最初のフィールドが処理された後にセパレータが設定されます-以前は必要なかったため
    sep = "、";

-最後に処理されたフィールドの後に改行を追加します-これはcsvレコード区切り文字を示します
    if(i == NF){printf "\ n"}
    }
} '
于 2016-10-13T12:15:43.613 に答える
4

sedを使ってみませんか?ほとんどの(すべて?)LinuxOSに標準で付属しています。

sed 's/\t/<your_field_delimiter>/g'

この例では、GNU sed(Linux)を使用しています。POSIX sed(AIX / Solaris)の場合、代わりにリテラルTABを入力すると思います\t

例(CSV出力の場合):

#mysql mysql -B -e "select * from user" | while read; do sed 's/\t/,/g'; done

localhost,root,,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,,,,,0,0,0,0,,
localhost,bill,*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,,,,,0,0,0,0,,
127.0.0.1,root,,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,,,,,0,0,0,0,,
::1,root,,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,,,,,0,0,0,0,,
%,jim,*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,,,,,0,0,0,0,,
于 2015-07-01T06:07:16.610 に答える
2

mysqldumpユーティリティはあなたを助けることができます、基本的にそれはステートメント--tabのために包まれているオプションで。SELECT INTO OUTFILE

例:

mysqldump -u root -p --tab=/tmp world Country --fields-enclosed-by='"' --fields-terminated-by="," --lines-terminated-by="\n" --no-create-info

これにより、csv形式のファイルが作成されます/tmp/Country.txt

于 2013-03-26T22:46:00.897 に答える
1

mysqlクライアントを使用している場合は、セッションごとにresultFormatを設定できます。

mysql -h localhost -u root --resutl-format=json

また

mysql -h localhost -u root --vertical

ここで引数の完全なリストを確認してください。

于 2020-09-01T12:32:57.687 に答える
1

mysqlクライアントは出力fdを検出できます。fdがS_IFIFO(パイプ)の場合はASCIIテーブルを出力せず、fdが文字デバイス(S_IFCHR)の場合はASCIIテーブルを出力します。

--tableを使用して、次のようなASCIIテーブルを強制的に出力できます。

$mysql -t -N -h127.0.0.1 -e "select id from sbtest1 limit 1" | cat
+--------+
| 100024 |
+--------+

-t、-tableテーブル形式で出力します。

于 2020-12-25T15:11:05.870 に答える
1

spyqlを使用して、mysqlのタブ区切りの出力を読み取り、コンマ区切りのCSVを生成して、ヘッダーの書き込みをオフにすることができます。

$ mysql -e "SELECT 'Bill' AS people, 'Raleigh, NC' AS places" | spyql -Oheader=False "SELECT * FROM csv TO csv"
Bill,"Raleigh, NC"

spyqlは、入力にヘッダーがあるかどうか、および区切り文字は何かを検出します。出力区切り文字は、デフォルトではコンマです。必要に応じて、これらすべてのオプションを手動で指定できます。

$ mysql -e "SELECT 'Bill' AS people, 'Raleigh, NC' AS places" | spyql -Idelimiter="'\t'" -Iheader=True -Odelimiter="," -Oheader=False "SELECT * FROM csv TO csv"
Bill,"Raleigh, NC"

たとえば、CSVの代わりにJSONを生成することを選択した場合、spyqlはそれを利用できるため、mysqlでのヘッダー書き込みをオフにしません。

$ mysql -e "SELECT 'Bill' AS people, 'Raleigh, NC' AS places" | spyql "SELECT * FROM csv TO json" 
{"people": "Bill", "places": "Raleigh, NC"}

または、列を参照する必要がある場合:

$ mysql -e "SELECT 'Bill' AS people, 'Raleigh, NC' AS places" | spyql -Oindent=2 "SELECT *, 'I am {} and I live in {}.'.format(people, places) AS message FROM csv TO json"
{
  "people": "Bill",
  "places": "Raleigh, NC",
  "message": "I am Bill and I live in Raleigh, NC."
}

免責事項:私はspyqlの作者です

于 2022-01-04T08:03:30.763 に答える