Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
linux中将制表符分隔文件转换为csv的最快方法_Linux_Csv - Fatal编程技术网

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

linux中将制表符分隔文件转换为csv的最快方法,linux,csv,Linux,Csv,我有一个以制表符分隔的文件,它有超过2亿行。在linux中,将其转换为csv文件的最快方法是什么?这个文件确实有多行标题信息,我需要沿着这条路去掉这些信息,但是标题的行数是已知的。我已经看到了关于sed和gawk的建议,但我想知道是否有“首选”选择 只是澄清一下,此文件中没有嵌入制表符。如果您需要做的只是将所有制表符转换为逗号字符,tr可能是最好的选择 此处的空白是文字选项卡: $ echo "hello world" | tr "\\t" "," hello,world 当然,如果您在文

我有一个以制表符分隔的文件,它有超过2亿行。在linux中,将其转换为csv文件的最快方法是什么?这个文件确实有多行标题信息,我需要沿着这条路去掉这些信息,但是标题的行数是已知的。我已经看到了关于
sed
gawk
的建议,但我想知道是否有“首选”选择

只是澄清一下,此文件中没有嵌入制表符。

如果您需要做的只是将所有制表符转换为逗号字符,
tr
可能是最好的选择

此处的空白是文字选项卡:

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

当然,如果您在文件中的字符串文本中嵌入了制表符,这也会错误地转换这些内容;但是嵌入式文字制表符是相当少见的。

如果您担心嵌入式逗号,那么您需要使用稍微智能一些的方法。下面是一个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
python script.pyoutput.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//”,“/g'-e's/^/“/'-e's/$/”/'infle>outfile
该死的批评家,引用所有的话,CSV不在乎

是实际的制表符\这对我不起作用。在bash中,使用^V输入它。

perl-lpe的/“/”/g;s/^ |$/”/g;s/\t/“,”/g'output.csv
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" }'

@ignacio vazquez abrams的python解决方案很棒!对于希望在其他选项卡上解析分隔符的用户,该库实际上允许您设置任意分隔符。以下是我处理管道分隔文件的修改版本:

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)
  • 如果要将整个tsv文件转换为csv文件:

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

  • 如果要省略某些字段:

    $ cat data.tsv | cut -f1,2,3 | tr "\\t" "," > data.csv
    
    上述命令将data.tsv文件转换为仅包含前三个字段的data.csv文件


我认为最好不要对文件进行cat处理,因为它可能会在大文件的情况下产生问题。更好的方法可能是

$tr',''\t'tabdelimitedFile.txt

该命令将从csvfile.csv获取输入,并将结果存储为tabdelimitedFile.txt中的制表符,您也可以使用该制表符


在我对一个300MB tsv文件的测试中,它大约比python解决方案快5倍(2.5s比14s)。

右键单击文件,单击重命名,删除“t”并放置一个“c”。我不是开玩笑,大多数csv解析器都可以处理制表符分隔符。我现在有这个问题,为了我的目的,重命名工作得很好。

更常见的是在源代码中嵌入逗号,这需要用引号括起来。如果有嵌入的引号,这会很麻烦…感谢
tr
的建议。与sed相比,它的速度如何?假设您想跳过标题,从第x行开始,继续到文件的其余部分。有没有办法通过
tr
实现这一点?(我还应该澄清文件中没有嵌入逗号。)@andrewj:
tr
应该快得多,因为它只是逐个字符替换,而不是正则表达式匹配。至于跳过头,最简单的方法是只处理两个块——如果您知道长度,
head-n input>output;尾部-n+输入| tr…>>输出
;如果你不知道长度,可能是
grep-n
..@andrew,sed支持音译,也可以使用地址范围。这是一个不完整的答案<代码>“必须转换为
对于CSV,如果字段包含引号、逗号或换行符,则必须用
引号括起来(尽管换行符不会出现在以TSV表示的数据中)。除非您确定没有嵌入逗号和嵌入选项卡,否则这是一种非常可靠的方法。尽管它可能不符合“最快”的标准。它可能不是“最快”,但它确实能为我处理嵌入的制表符和逗号。这真是太棒了。我在bash中编写了一个神秘的sed脚本来处理这个问题,但这无法与python csv库的完整性相比。谢谢伊格纳西奥,谢谢你的提议。关于速度-易用性和可靠性,远远超过速度-这当然足够快了。:-)伊格纳西奥,如果您允许,我想将您的脚本和属性添加到我的库中的tab2csv中。@IgnacioVazquez Abrams:谢谢,伊格纳西奥。对我来说最好的答案,只有一个小小的改变,scape双引号:perl-lpe的/“/\”/g;s/^ |$/“/g;s/\t/”,“/g'<…Perl万岁!正是我需要的一行。你是一个救世主,多年没有使用过这种语言,完美而快速!有关csv到tsv和嵌入分隔符的问题,请参阅(也相关:)的答案。对于tab,你可以执行
sed-e's/“/\\”/g'-e“s/\t/\”,\“/g”-e's/^'-e's/'-s/$/“/”infle>outfile
。感谢您推荐xsv。我一直在寻找一个快速CSV工具包有一段时间了。
$ cat data.tsv | tr "\\t" "," > data.csv
$ cat data.tsv | cut -f1,2,3 | tr "\\t" "," > data.csv
xsv input -d '\t' input.tsv > output.csv