我有一个制表符分隔的文件,它拥有超过2亿行。在linux中将其转换为csv文件的最快方式是什么?这个文件确实有多行标题信息,我需要将它们排除在外,但标题的行数是已知的。我看到sed
和gawk
的建议,但我想知道是否有“首选”选项。最快的方式将制表符分隔的文件转换为linux中的csv
只是为了澄清,此文件中没有嵌入式选项卡。
我有一个制表符分隔的文件,它拥有超过2亿行。在linux中将其转换为csv文件的最快方式是什么?这个文件确实有多行标题信息,我需要将它们排除在外,但标题的行数是已知的。我看到sed
和gawk
的建议,但我想知道是否有“首选”选项。最快的方式将制表符分隔的文件转换为linux中的csv
只是为了澄清,此文件中没有嵌入式选项卡。
如果您只需要做的是翻译所有制表符到逗号字符,tr
可能是要走的路。
这里的空格是文字标签:
$ echo "hello world" | tr "\\t" ","
hello,world
当然,如果你已经在文件中嵌入字符串文字内的标签,这会不正确地翻译那些为好;但嵌入的文字标签将是相当不常见的。
更常见的是在源代码中嵌入逗号,然后需要用引号包装。如果有嵌入式引用,这很麻烦... – kibibu 2010-03-29 01:09:15
感谢您提供'tr'建议。它如何与速度相比'sed'?假设您想要跳过行号为x的头文件并继续执行文件的其余部分。有没有一种方法可以用'tr'来实现呢? (我也应该澄清,文件中没有嵌入逗号。) – andrewj 2010-03-29 01:10:04
@andrewj:'tr'应该快得多,因为它只是逐字替换而不是正则表达式匹配。至于跳过标题,最简单的事情就是只处理两个区块 - 如果你知道长度,可以输入“head -n
如果您担心嵌入逗号,那么您需要使用稍微更智能的方法。下面是一个Python脚本,从标准输入采用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
假设你不想改变头和假设您没有嵌入式选项卡
# 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)
sed -e 's/"/\\"/g' -e 's/<tab>/","/g' -e 's/^/"/' -e 's/$/"/' infile > outfile
该死的批评家,报价一切,CSV并不关心。
<tab>
是实际的制表符。 \ t不适合我。在bash中,使用^ V输入它。
For你可以做'sed -e's /“/ \\”/ g'-e“s/\ t/\”,\“/ g”-e's/^ /“/'-e's/$ /“/'infile> outfile'。 – 2016-01-12 19:24:43
perl -lpe 's/"/""/g; s/^|$/"/g; s/\t/","/g' <input.tab> output.csv
Perl比sed,awk和Python更快。
以下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""""
@伊格纳西奥 - 巴斯克斯 - 艾布拉姆斯的蟒蛇的解决方案是伟大的!对于那些希望解析分隔符其他选项卡的人来说,该库实际上允许您设置任意分隔符。下面是我修改的版本来处理竖线分隔的文件:如果你想整个TSV文件转换成csv文件
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)
:
$ cat data.tsv | tr "\\t" "," > data.csv
如果你想省略一些字段:
$ cat data.tsv | cut -f1,2,3 | tr "\\t" "," > data.csv
上面的命令会将data.tsv文件转换为仅包含前三个字段的data.csv文件。
很好:) – 2017-07-25 03:50:33
对于CSV以TSV和嵌入式分隔符的问题,又见回答到http://stackoverflow.com/questions/13475535/replace-every-comma-not-enclosed-in-a-pair-of-double - (与相关的:http://unix.stackexchange.com/questions/48672/remove-comma-between-the-quotes-only-in-a-comma-delimited-file)。 – 2015-12-26 21:18:56