将 CSV 转换为 TSV

34 python perl text-processing csv

我有许多大型 CSV 文件,并希望它们采用 TSV(制表符分隔格式)。复杂的是CSV文件的字段中有逗号,例如:

 A,,C,"D,E,F","G",I,"K,L,M",Z
Run Code Online (Sandbox Code Playgroud)

预期输出:

 A      C   D,E,F   G   I   K,L,M   Z
Run Code Online (Sandbox Code Playgroud)

(中间的空格是“硬”标签)

我在这台服务器上安装了 Perl、Python 和 coreutils。

One*_*eer 49

Python

添加到名为 的文件csv2tab,并使其可执行

touch csv2tab && chmod u+x csv2tab

添加到它

#!/usr/bin/env python
import csv, sys
csv.writer(sys.stdout, dialect='excel-tab').writerows(csv.reader(sys.stdin))
Run Code Online (Sandbox Code Playgroud)

试运行

$ echo 'A,,C,"D,E,F","G",I,"K,L,M",Z' | ./csv2tab                     
A       C   D,E,F   G   I   K,L,M   Z
Run Code Online (Sandbox Code Playgroud)

$ ./csv2tab < data.csv > data.tsv && head data.tsv                                                   
1A      C   D,E,F   G   I   K,L,M   Z
2A      C   D,E,F   G   I   K,L,M   Z
3A      C   D,E,F   G   I   K,L,M   Z
Run Code Online (Sandbox Code Playgroud)

  • @kev 此代码不需要 X 服务器,因此您似乎还有其他问题 (2认同)

Nei*_*gan 28

使用csvkit(Python),例如:

$ csvformat -T in.csv > out.txt
Run Code Online (Sandbox Code Playgroud)

使用正确的 CSV 和 TSV 引用和转义进行流式传输

它在 apt 和其他包管理器中

  • 我用来修复引用的命令行: csvformat -U 3 -Q "" -T in.csv &gt; out.tsv (2认同)

tri*_*eee 22

为了好玩,sed

sed -E 's/("([^"]*)")?,/\2\t/g' file
Run Code Online (Sandbox Code Playgroud)

如果您sed不支持-E,请尝试使用-r。如果您sed不支持\t文字制表符,请尝试放置文字制表符(在许多 shell 中,ctrl- v tab)或在 Bash 中,使用$'...'C 样式字符串(在这种情况下,\2需要将反斜杠加倍)。如果要保留引号,请使用\1而不是\2(在这种情况下,内对括号没有用,可以删除)。

如果您sed不支持-E-r,请尝试

sed -E 's/("([^"]*)")?,/\2\t/g' file
Run Code Online (Sandbox Code Playgroud)

如果\t不支持,可能再次进行相同的调整。

这不会尝试处理双引号内的转义双引号;一些 CSV 方言通过将双引号 (sic) 加倍来支持这一点。


ste*_*ver 15

一种选择可能是 perl 的Text::CSV模块,例如

perl -MText::CSV -lne 'BEGIN { $csv = Text::CSV->new() }
  print join "\t", $csv->fields() if $csv->parse($_)
' somefile
Run Code Online (Sandbox Code Playgroud)

展示

echo 'A,,C,"D,E,F","G",I,"K,L,M",Z' |
  perl -MText::CSV -lne 'BEGIN { $csv = Text::CSV->new() }
  print join "\t", $csv->fields() if $csv->parse($_)
'
A       C   D,E,F   G   I   K,L,M   Z
Run Code Online (Sandbox Code Playgroud)


小智 8

珀尔

perl -lne '
   my $re = qr/,(?=(?:[^"]*"[^"]*")*(?![^"]*"))/;
   print join "\t", map { s/(?<!\\)"//gr =~ s/\\"/"/gr } split $re;
'
Run Code Online (Sandbox Code Playgroud)

awk

awk -v Q=\" -v FPAT="([^,]*)|(\"[^\"]+\")" -v OFS="\t" '{
   for (i=1; i<=NF; ++i)
      if ( substr($i, 1, 1) == Q )
         $i = substr($i, 2, length($i) - 2)
   print $1, $2, $3, $4, $5, $6, $7, $8
}'
Run Code Online (Sandbox Code Playgroud)

结果:

A               C       D,E,F   G       I       K,L,M   Z
Run Code Online (Sandbox Code Playgroud)


Jon*_*Deg 7

我编写了一个开源的 CSV 到 TSV 转换器来处理所描述的转换。它非常快,如果持续需要转换大型 CSV 文件,可能值得一看。该工具是eBay 的 TSV 实用程序工具包此处为csv2tsv 文档)的一部分。默认选项足以满足所描述的输入:

$ csv2tsv file.csv > file.tsv
Run Code Online (Sandbox Code Playgroud)

将 CSV 转换为 TSV 时的一个考虑因素是处理数据中的字段和记录分隔符(逗号和换行符)。CSV 使用转义语法。如果目标是使用输出与Unix工具一样cutawk等等,输出需要自由逃逸。当数据中包含分隔符时,此处列出的大多数解决方案都会生成 CSV 样式的转义符。csv2tsv与其他解决方案的不同之处在于它产生没有逃逸的 TSV。有关详细信息,请参阅文档。

要查看特定解决方案的作用,请转换数据中包含逗号、制表符、引号和换行符的 CSV。例如:

$ echo $'Line,Field1,Field2\n1,"Comma: |,|","Quote: |""|"\n"2","TAB: |\t|","Newline: |\n|"' | <conversion-script-or-command>
Run Code Online (Sandbox Code Playgroud)

生成转义的解决方案将在包含引号、换行符或制表符的字段周围放置双引号。


chx*_*chx 6

热核苍蝇拍解决方案必须使用 libreoffice。虽然https://ask.libreoffice.org/en/question/19042/is-is-possible-to-convert-comma-separated-value-csv-to-tab-separated-value-tsv-via-headless-mode /表明这是不可能的,但它是错误的(或者只是过时了?)并且以下命令适用于我的 5.3.:

loffice "-env:UserInstallation=file:///tmp/LibO_Conversion" --convert-to csv:"Text - txt - csv (StarCalc)":9,34,UTF8 --headless --outdir some/path --infilter='csv:44,34,UTF8' *.csv

env可以跳过该参数,但这样文档就不会出现在您最近的文档中。

  • 我认为真正的热核苍蝇拍应该是通过 LibreOffice 的 UNO API 编写一个 Java 实用程序来完成它:)。 (2认同)

Kei*_*son 5

如果您拥有或可以安装该csvtool实用程序:

csvtool -t COMMA -u TAB cat in.csv > out.ctv
Run Code Online (Sandbox Code Playgroud)

请注意,由于某种原因csvtool没有手册页,但csvtool --help会打印几百行文档。


agc*_*agc 5

使用mlr几乎是简洁的,但禁用标头需要很长的选项:

mlr --c2t --implicit-csv-header --headerless-csv-output cat file.csv 
Run Code Online (Sandbox Code Playgroud)

输出:

A       C   D,E,F   G   I   K,L,M   Z
Run Code Online (Sandbox Code Playgroud)