最快的方式将制表符分隔的文件转换为Linux中的csv

我有一个制表符分隔的文件,有超过2亿行。 什么是最快的方式在Linux中将其转换为CSV文件? 这个文件确实有多行标题信息,我需要在路上去除,但标题的行数是已知的。 我已经看到了sedgawkbuild议,但是我想知道是否有“首选”的select。

只是为了澄清,在这个文件中没有embedded式标签。

如果您只需要将所有制表符转换为逗号字符,则tr可能是要走的路。

这里的空格是一个文字标签:

 $ echo "hello world" | tr "\\t" "," hello,world 

当然,如果你在文件中embedded了string文字中的标签,这也会错误地翻译这些标签。 但embedded的文字标签将是相当罕见的。

如果你担心embedded的逗号,那么你需要使用一个稍微聪明的方法。 以下是一个Python脚本,它从stdin中取出TSV行,并将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) 

从shell运行它如下:

 python script.py < input.tsv > output.csv 
 perl -lpe 's/"/""/g; s/^|$/"/g; s/\t/","/g' < input.tab > output.csv 

Perl比sed,awk和Python更快。

 sed -e 's/"/\\"/g' -e 's/<tab>/","/g' -e 's/^/"/' -e 's/$/"/' infile > outfile 

该死的评论家,引用一切,CSV不在乎。

<tab>是实际的制表符。 \我没有为我工作。 在bash中,使用^ V来input它。

@ ignacio-vazquez-abrams的python解决scheme非常棒! 对于正在分析其他选项卡的人来说,库实际上允许你设置任意的分隔符。 这里是我的修改版本来处理pipe道分隔的文件:

 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) 

假设您不想更改标题并假定您没有embedded的选项卡

 # cat file header header header one two three $ awk 'NR>1{$1=$1}1' OFS="," file header header header one,two,three 

NR> 1跳过第一个标题。 你提到你知道多less行标题,所以使用正确的数字为你自己的情况。 有了这个,你也不需要调用任何其他的外部命令。 只有一个awk命令可以完成这项工作。

另一种方式,如果你有空白列,你在乎。

 awk 'NR>1{gsub("\t",",")}1' file 

使用sed

 sed '2,$y/\t/,/' file #skip 1 line header and translate (same as tr) 
  • 如果你想把整个tsv文件转换成一个csv文件:

     $ cat data.tsv | tr "\\t" "," > data.csv 

  • 如果你想省略一些字段:

     $ cat data.tsv | cut -f1,2,3 | tr "\\t" "," > data.csv 

    上面的命令会将data.tsv文件转换为仅包含前三个字段的data.csv文件。

下面的awk oneliner支持引用+引用转义

 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""""