我有一个输出表格的程序,我想知道 csv 和 tsv 格式之间是否有任何优点/缺点。
5 回答
TSV 是一种非常高效的 Javascript/Perl/Python 处理方式,不会丢失任何输入信息,也易于人类阅读。
自公开发布以来,4store 已支持该格式,并且被广泛使用。
我的看法是:CSV 用于加载到电子表格中,TSV 用于由定制软件进行处理。
选择取决于应用程序。简而言之,如果您的字段不包含逗号,请使用 CSV;否则 TSV 是要走的路。
TL;博士
在这两种格式中,当分隔符出现在字段中时就会出现问题,因此有必要指出分隔符不是作为字段分隔符而是作为字段内的值,这可能会有些痛苦。
例如,使用 CSV: Kalman, Rudolf
, von Neumann, John
,Gabor, Dennis
一些基本的方法是:
删除字段中出现的所有分隔符。
例如
Kalman Rudolf
,von Neumann John
,Gabor Dennis
转义字符(通常预先附加一个反斜杠
\
)。例如
Kalman\, Rudolf
,von Neumann\, John
,Gabor\, Dennis
用其他字符(通常是双引号
"
)将每个字段括起来。例如
"Kalman, Rudolf"
,"von Neumann, John"
,"Gabor, Dennis"
CSV
字段用逗号分隔,
。
例如:
Name,Score,Country
Peter,156,GB
Piero,89,IT
Pedro,31415,ES
好处:
- 与非技术人员共享时,它更加通用和有用,因为大多数软件包无需玩设置即可阅读。
缺点:
- 在字段中转义逗号可能会令人沮丧,因为并非每个人都遵循标准。
- 所有额外的转义字符和引号都会增加最终文件大小的权重。
硅通孔
字段由表格分隔<TAB>
或\t
例如:
Name<TAB>Score<TAB>Country
Peter<TAB>156<TAB>GB
Piero<TAB>89<TAB>IT
Pedro<TAB>31415<TAB>ES
好处:
- 不必转义分隔符,因为在字段中通常不包含制表符。否则,应将其删除。
缺点:
- 它不太普遍。
你可以使用任何你想要的分隔符,但是许多应用程序都支持制表符和逗号,包括 Excel、MySQL、PostgreSQL。逗号在文本字段中很常见,因此如果您对它们进行转义,则需要对它们中的更多进行转义。如果您不转义它们并且您的字段可能包含逗号,那么您就不能自信地在您的文件上运行“sort -k2,4”。无论如何,您可能需要转义字段中的某些字符(空字节、换行符等)。由于这些原因以及更多原因,我更喜欢使用 TSV,并在字段中转义制表符、空字节和换行符。此外,使用 TSV 通常更容易。只需用制表符分隔每一行。对于 CSV,有带引号的字段,可能是带有换行符的字段等。我只在被迫时才使用 CSV。
我认为通常 csv 比 tsv 格式更受支持。
TSV-utils做了一个有趣的比较,之后复制到这里。简而言之,使用 TSV。
比较 TSV 和 CSV 格式
TSV 和 CSV 格式之间的差异可能令人困惑。明显的区别是默认字段分隔符:TSV 使用 TAB,CSV 使用逗号。两者都使用换行符作为记录分隔符。
就其本身而言,使用不同的字段分隔符并不是特别重要。更重要的是数据中出现的分隔符的方法。CSV 使用转义语法来表示数据中的逗号和换行符。TSV 采用不同的方法,不允许在数据中使用 TAB 和换行符。
转义语法使 CSV 能够完全表示常见的书面文本。这非常适合人工编辑的文档,尤其是电子表格。这种普遍性是有代价的:阅读它需要程序来解析转义语法。虽然不是太难,但仍然很容易做错,尤其是在编写一次性程序时。在处理 CSV 文件时,最好使用 CSV 解析器。传统的 Unix 工具(如cut
, sort
, awk
, )diff
不处理 CSV 转义,需要其他工具。
相比之下,解析 TSV 数据很简单。readline
可以使用大多数编程语言中的典型例程来读取记录。可以使用split
例程找到每条记录中的字段。可以通过提供正确的字段分隔符来调用 Unix 实用程序,awk -F "\t"
例如sort -t $'\t'
. 不需要特殊的解析器。这要可靠得多。它也更快,解析转义语法不使用 CPU 时间。
速度优势对于面向记录的操作尤其明显。记录计数 ( wc -l
)、重复数据删除 ( uniq
, tsv-uniq)、文件分割 ( head
, tail
, split
)、洗牌 (GNU shuf
, tsv-sample) 等。TSV 更快,因为可以使用高度优化的换行搜索例程 (例如memchr
) 找到记录边界。识别 CSV 记录边界需要完全解析每条记录。
这些特性使 TSV 格式非常适合数据挖掘和机器学习环境中常见的大型表格数据集。这些数据集在字段中很少需要制表符和换行符。
最常见的 CSV 转义格式使用引号来分隔包含分隔符的字段。引号也必须被转义,这是通过使用一对引号来表示单引号来完成的。考虑下表中的数据:
字段 1 | 字段 2 | 字段 3 |
---|---|---|
美国广播公司 | 你好世界! | 定义 |
吉 | 说“你好,世界!” | jkl |
在 Field-2 中,第一个值包含逗号,第二个值包含引号和逗号。这是 CSV 表示,使用转义来表示数据中的逗号和引号。
Field-1,Field-2,Field-3
abc,"hello, world!",def
ghi,"Say ""hello, world!""",jkl
在上面的示例中,仅引用了带分隔符的字段。引用所有字段也很常见,无论它们是否包含分隔符。以下 CSV 文件是等效的:
"Field-1","Field-2","Field-3"
"abc","hello, world!","def"
"ghi","Say ""hello, world!""","jkl"
这是 TSV 中的相同数据。它更简单,因为不涉及转义:
Field-1 Field-2 Field-3
abc hello, world! def
ghi Say "hello, world!" jkl
TSV 和 CSV 之间的相似性可能会导致混淆哪些工具是合适的。进一步加深这种混淆,使用逗号作为字段分隔符的数据文件有些常见,但在数据中没有逗号、引号或换行符。这些文件中不需要 CSV 转义,这意味着传统的 Unix 工具喜欢cut
并且awk
可以用来处理这些文件。此类文件有时称为“简单 CSV”。它们等效于以逗号作为字段分隔符的 TSV 文件。传统的 Unix 工具和 tsv-utils 工具可以通过指定字段分隔符来正确处理这些文件。但是,“简单 csv”是一个非常临时且定义不明确的概念。处理这些文件时的一个简单预防措施是在其他处理步骤之前运行 CSV 到 TSV 转换器,如 csv2tsv。
请注意,许多 CSV 到 TSV 的转换工具实际上并没有删除 CSV 转义。相反,许多工具将逗号替换为 TAB 作为记录分隔符,但仍使用 CSV 转义来表示数据中的 TAB、换行符和引号字符。此类数据无法由 Unix 工具(如sort
、awk
和cut
. tsv-utils 中的 csv2tsv 工具通过将 TAB 和换行符替换为空格(可自定义)来避免转义。这适用于绝大多数数据挖掘场景。
要查看特定的 CSV 到 TSV 转换工具的作用,请转换包含引号、逗号、制表符、换行符和双引号字段的 CSV 数据。例如:
$ echo $'Line,Field1,Field2\n1,"Comma: |,|","Quote: |""|"\n"2","TAB: |\t|","Newline: |\n|"' | <csv-to-tsv-converter>
生成 CSV 转义的方法会将许多输出字段括在双引号中。
参考:
- 维基百科:制表符分隔值- TSV 格式的有用描述。
- IANA TSV 规范- 制表符分隔值 mime 类型的正式定义。
- Wikipedia: Comma-separated-values - 描述 CSV 和相关格式。
- RFC 4180 - IETF CSV 格式描述,最接近 CSV 的实际标准。
- brendano/tsvutils:tsvutils 的哲学- Brendan O'Connor 关于在他的开源工具包中使用 TSV 格式的基本原理的讨论。
- 那么您想编写自己的 CSV 代码吗?- Thomas Burette 的幽默而准确的博客文章描述了临时 CSV 解析的问题。当然,您可以使用 TSV 并避免这些问题!