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