我有一些TSV文件需要转换成CSV文件。有没有在BASH中的解决方案,例如使用awk
来进行转换?我可以使用sed
,像这样,但担心会出现一些错误:
sed 's/\t/,/g' file.tsv > file.csv
- 不需要添加引号。
如何将TSV文件转换为CSV文件?
我有一些TSV文件需要转换成CSV文件。有没有在BASH中的解决方案,例如使用awk
来进行转换?我可以使用sed
,像这样,但担心会出现一些错误:
sed 's/\t/,/g' file.tsv > file.csv
如何将TSV文件转换为CSV文件?
tr '\t' ',' < file.tsv > file.csv
sed:
如果输入不包含带有可能嵌入 \t
字符的引号字符串,那么 OP 自己的 sed
解决方案完全可以胜任。
sed 's/\t/,/g' file.tsv > file.csv
唯一的注意事项是,在某些平台上(例如 macOS),转义序列 \t
不受支持,因此必须使用 ANSI 引用($'\t'
)将文字制表符插入命令字符串中:
sed 's/'$'\t''/,/g' file.tsv > file.csv
awk:
awk
的注意点是必须明确地将输入字段分隔符 FS
设置为 \t
,否则默认行为会剥离前导和尾随制表符,并且将多个制表符的内部跨度替换为单个逗号 ,
:
awk 'BEGIN { FS="\t"; OFS="," } {$1=$1; print}' file.tsv > file.csv
$1
分配给它本身会导致awk
使用OFS
重新构建输入行 - 输出字段分隔符;这实际上将所有\t
字符替换为,
字符。然后print
只需打印重建的行。
awk
解决方案:
正如A. Rabus指出的那样,上面的解决方案不能正确处理未引用的输入字段,这些字段本身包含,
字符 - 你最终会得到额外的CSV字段。awk
解决方案通过根据需要在"..."
中封装这些字段来解决此问题(有关方法的部分解释,请参见上面的非健壮的awk
解决方案)。"
字符,则根据RFC 4180对其进行转义为""
。感谢Wyatt Israel。
awk 'BEGIN { FS="\t"; OFS="," } {
rebuilt=0
for(i=1; i<=NF; ++i) {
if ($i ~ /,/ && $i !~ /^".*"$/) {
gsub("\"", "\"\"", $i)
$i = "\"" $i "\""
rebuilt=1
}
}
if (!rebuilt) { $1=$1 }
print
}' file.tsv > file.csv
$i ~ /[,"]/ && $i !~ /^".*"$/
可以检测到任何包含,
和/或"
但尚未被双引号括起来的字段
gsub("\"", "\"\"", $i)
通过加倍嵌入的"
字符来转义
$i = "\"" $i "\""
更新结果,将其用双引号括起来
如前所述,更新任何字段都会导致awk
从带有OFS
值的字段中重新构建该行,即在这种情况下为,
,这相当于有效的TSV -> CSV转换;标志rebuilt
用于确保每个输入记录至少重建一次。
\t
是awk
默认情况下处理输入字段分隔符之一,因此人们可能会认为在此处设置输入字段分隔符是不必要的-这是一个谬论,原因如我所指出的那样;因此需要注意。至于tr
和sed
:输入字段分隔符的概念不适用。 - mklement0tr
是所述工作的正确工具,因此这可能是一个无意义的观点。 - Ed Morton这也可以通过Perl实现:
要将结果导入新的输出文件,您可以使用以下命令:
perl -wnlp -e 's/\t/,/g;' input_file.tsv > output_file.csv
如果您想直接编辑文件,可以使用-i选项:
perl -wnlpi -e 's/\t/,/g;' input_file.txt
如果你发现你处理的实际上不是制表符(tab),而是多个空格,则可以使用以下命令用逗号替换每个出现的两个或多个空格:
perl -wnlpi -e 's/\s+/,/g;' input_file
请注意,\s
表示任何空白字符,包括空格、制表符或换行符,并且不能在替换字符串中使用。
:%s/\t/,/g
这样可以让你立即查看结果,并在需要时通过单个按钮按下(u)来撤消它们。 - Toby将tsv转换为csv
awk 'BEGIN { FS="\t"; OFS="," } {$1=$1; print}' file.tsv > file.csv
awk 'BEGIN { FS=","; OFS="\t" } {$1=$1; print}' file.csv > file.tsv
您可以在shell中简单地使用sed
的强大功能:
sed -r 's/\t/","/g' file.tsv|sed -r 's/(^|$)/"/g' > file.csv
tsv
文件转换为 csv
。然而,tsv
文件可能包含数字字段。在这种情况下,它们不应该像 "123456"
那样被双引号所包围。因此我们需要另一个阶段,以便删除此类双引号。最终解决方案:sed -r 's/\t/","/g' file.tsv|sed -r 's/(^|$)/"/g'|sed -r 's/"([0-9]+)"/\1/g' > file.csv
tr 命令:
tr '\t' ',' < file.tsv > file.csv
这个程序非常简单,对我来说即使在一个非常大的文件(约10 GB)上也能够给出绝对正确和非常快速的结果。