Быстрый способ конвертировать файл с разделителями-запятыми в csv в linux
У меня есть файл с разделителями табуляции, который имеет более 200 миллионов строк. Какой самый быстрый способ в linux преобразовать это в файл csv? У этого файла есть несколько строк информации заголовка, которые мне нужно разбить по дороге, но известно количество строк заголовка. Я видел предложения для sed
и gawk
, но мне интересно, есть ли "предпочтительный" выбор.
Чтобы уточнить, в этом файле нет встроенных вкладок.
Ответы
Ответ 1
Если все, что вам нужно сделать, это перевести все символы табуляции на символы запятой, tr
- это, вероятно, путь.
Пустое пространство здесь является литеральной вкладкой:
$ echo "hello world" | tr "\\t" ","
hello,world
Конечно, если у вас встроенные вкладки внутри строковых литералов в файле, это также неверно переведет их; но встроенные литеральные вкладки были бы довольно необычными.
Ответ 2
Если вы беспокоитесь о встроенных запятых, вам нужно использовать несколько более интеллектуальный метод. Здесь Python script, который берет TSV-строки из stdin и записывает CSV-строки в stdout:
import sys
import csv
tabin = csv.reader(sys.stdin, dialect=csv.excel_tab)
commaout = csv.writer(sys.stdout, dialect=csv.excel)
for row in tabin:
commaout.writerow(row)
Запустите его из оболочки следующим образом:
python script.py < input.tsv > output.csv
Ответ 3
perl -lpe 's/"/""/g; s/^|$/"/g; s/\t/","/g' < input.tab > output.csv
Perl, как правило, быстрее в таких вещах, как sed, awk и Python.
Ответ 4
sed -e 's/"/\\"/g' -e 's/<tab>/","/g' -e 's/^/"/' -e 's/$/"/' infile > outfile
Черт, критики, цитируйте все, CSV не волнует.
<tab>
- это фактический символ табуляции. \t не работал у меня. В bash используйте ^ V, чтобы ввести его.
Ответ 5
-
Если вы хотите преобразовать весь файл tsv в файл csv:
$ cat data.tsv | tr "\\t" "," > data.csv
-
Если вы хотите опустить некоторые поля:
$ cat data.tsv | cut -f1,2,3 | tr "\\t" "," > data.csv
Вышеупомянутая команда преобразует файл data.tsv в файл data.csv , содержащий только первые три поля.
Ответ 6
@Инициатива python от ignacio-vazquez-abrams великолепна! Для людей, которые ищут разбор разметки другой вкладки, библиотека фактически позволяет вам установить произвольный разделитель. Вот моя модифицированная версия для обработки файлов с разделителями-ограничителями:
import sys
import csv
pipein = csv.reader(sys.stdin, delimiter='|')
commaout = csv.writer(sys.stdout, dialect=csv.excel)
for row in pipein:
commaout.writerow(row)
Ответ 7
предполагая, что вы не хотите изменять заголовок и предполагаете, что у вас нет встроенных вкладок
# cat file
header header header
one two three
$ awk 'NR>1{$1=$1}1' OFS="," file
header header header
one,two,three
NR > 1 пропускает первый заголовок. вы упомянули, что знаете, сколько строк заголовка, поэтому используйте правильный номер для своего собственного дела. с этим вам также не нужно вызывать другие внешние команды. эта команда выполняет только одну команду awk.
иначе, если у вас есть пустые столбцы, и вам это нужно.
awk 'NR>1{gsub("\t",",")}1' file
с помощью sed
sed '2,$y/\t/,/' file #skip 1 line header and translate (same as tr)
Ответ 8
следующий awk oneliner поддерживает цитирование + quote-escaping
printf "flop\tflap\"" | awk -F '\t' '{ gsub(/"/,"\"\"\"",$i); for(i = 1; i <= NF; i++) { printf "\"%s\"",$i; if( i < NF ) printf "," }; printf "\n" }'
дает
"flop","flap""""
Ответ 9
Вы также можете использовать xsv для этого
xsv input -d '\t' input.tsv > output.csv
В моем тесте на 300 МБ TSV файле он был примерно в 5 раз быстрее, чем решение Python (2,5 с против 14 с).
Ответ 10
Я думаю, что лучше не катать файл, потому что это может создать проблему в случае большого файла. Лучший способ может быть
$ tr ',' '\t' < csvfile.csv > tabdelimitedFile.txt
Команда получит входные данные из csvfile.csv и сохранит результат как разделенную вкладку в tabdelimitedFile.txt