Как вывести результаты запроса MySQL в формате CSV? - PullRequest
1050 голосов
/ 10 декабря 2008

Есть ли простой способ выполнить запрос MySQL из командной строки Linux и вывести результаты в формате CSV ?

Вот что я сейчас делаю:

mysql -u uid -ppwd -D dbname << EOQ | sed -e 's/        /,/g' | tee list.csv
select id, concat("\"",name,"\"") as name
from students
EOQ

Это становится грязным, когда есть много столбцов, которые должны быть заключены в кавычки, или если в результатах есть кавычки, которые нужно экранировать.

Ответы [ 29 ]

1602 голосов
/ 10 декабря 2008

С http://www.tech -recipes.com / rx / 1475 / save-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';

При использовании этой команды имена столбцов не будут экспортироваться.

Также обратите внимание, что /var/lib/mysql-files/orders.csv будет на сервере , на котором работает MySQL. Пользователь, под которым выполняется процесс MySQL, должен иметь права на запись в выбранный каталог, иначе команда не будет выполнена.

Если вы хотите записать вывод на локальный компьютер с удаленного сервера (особенно с размещенной или виртуализированной машины, такой как Heroku или Amazon RDS), это решение не подходит.

407 голосов
/ 08 апреля 2010
$ mysql your_database --password=foo < my_requests.sql > out.csv

Который разделен табуляцией. Передайте это так, чтобы получить настоящий CSV (спасибо @therefromhere):

... .sql | sed 's/\t/,/g' > out.csv
192 голосов
/ 30 сентября 2009

mysql --batch, -B

Печать результатов с использованием табуляции в качестве разделителя столбцов, с каждой строкой новая линия. С этой опцией mysql не использует файл истории. Пакетный режим приводит к нетабличному формату вывода и экранированию специальные символы. Экранирование может быть отключено с помощью необработанного режима; увидеть описание параметра --raw.

Это даст вам файл, разделенный табуляцией. Поскольку запятые (или строки, содержащие запятую) не экранированы, изменить разделитель на запятую непросто.

123 голосов
/ 22 марта 2011

Вот довольно грубый способ сделать это. Нашел где-то, не могу взять кредит

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

Работает довольно хорошо. Еще раз, хотя регулярное выражение доказывает только запись.


Regex Объяснение:

  • 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
80 голосов
/ 11 октября 2012

Unix / Только Cygwin , передайте через 'tr':

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

N.B .: Здесь не обрабатываются ни запятые, ни вкладки.

41 голосов
/ 29 января 2016

Это спасло меня пару раз. Быстро и все работает!

- партия Печать результатов с использованием 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

Для полноты вы можете преобразовать в CSV (но будьте осторожны , потому что вкладки могут быть внутри значений полей - например, текстовых полей)

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

37 голосов
/ 22 июня 2010

Решение OUTFILE, данное Полом Томблином (Paul Tomblin), заставляет записывать файл на самом сервере MySQL, поэтому это будет работать, только если у вас есть доступ FILE , а также доступ для входа или другие средства для получения файл из этого ящика.

Если у вас нет такого доступа, и вывод с разделителями табуляции является разумной заменой CSV (например, если ваша конечная цель - импорт в Excel), тогда решение Serbaut (с использованием mysql --batch и, необязательно, --raw) ) это путь.

34 голосов
/ 26 июня 2012

MySQL Workbench может экспортировать наборы записей в CSV, и, похоже, очень хорошо обрабатывает запятые в полях. CSV открывается в OpenOffice нормально.

32 голосов
/ 10 ноября 2011

Как насчет:

mysql your_database -p < my_requests.sql | awk '{print $1","$2}' > out.csv
26 голосов
/ 11 октября 2013

Все решения, представленные на сегодняшний день, за исключением одного из MySQL, являются неверными и, возможно, небезопасными (то есть проблемами безопасности) по крайней мере для некоторого возможного содержимого в базе данных mysql.

MYSQL Workbench (и аналогично PHPMyAdmin) предоставляют формально правильное решение, но предназначены для загрузки вывода в местоположение пользователя. Они не так полезны для таких вещей, как автоматизация экспорта данных.

Невозможно сгенерировать надежно правильный CSV из вывода mysql -B -e 'SELECT ...', потому что это не может кодировать возврат каретки и пробел в полях. Флаг -s для mysql действительно экранирует обратную косую черту и может привести к правильному решению. Тем не менее, использование языка сценариев (язык с достойной внутренней структурой данных, а не bash) и библиотек, где проблемы кодирования уже были тщательно проработаны, гораздо безопаснее.

Я подумал о написании сценария для этого, но как только я подумал о том, что я бы назвал, мне пришло в голову поискать ранее существующую работу с тем же именем. Хотя я не прошел через это полностью, решение на https://github.com/robmiller/mysql2csv выглядит многообещающим. В зависимости от вашего приложения, подход yaml к указанию команд SQL может или не может понравиться. Я также не в восторге от требования более свежей версии ruby, чем стандартная комплектация для моего ноутбука Ubuntu 12.04 или серверов Debian Squeeze. Да, я знаю, что мог бы использовать RVM, но я бы предпочел не поддерживать это для такой простой цели.

Надеюсь, кто-нибудь укажет подходящий инструмент, который прошел небольшое тестирование. В противном случае я, вероятно, обновлю это, когда найду или напишу.

...