我有一些TSV文件,我需要转换为CSV文件.BASH中是否有任何解决方案,例如使用awk,转换这些?我可以sed像这样使用,但我担心它会犯一些错误:
sed 's/\t/,/g' file.tsv > file.csv
Run Code Online (Sandbox Code Playgroud)
如何将TSV转换为CSV?
mkl*_*nt0 13
更新:以下解决方案通常不健壮,尽管它们在OP的特定用例中有效; 请参阅底部部分,了解强大awk的解决方案.
总结一下这些选项(有趣的是,它们的表现大致相同):
tr:
devnull的解决方案(在对问题的评论中提供)是最简单的:
tr '\t' ',' < file.tsv > file.csv
Run Code Online (Sandbox Code Playgroud)
sed:
sed鉴于输入不包含带引号的字符串(可能包含嵌入\t字符),OP自己的解决方案非常精细.
sed 's/\t/,/g' file.tsv > file.csv
Run Code Online (Sandbox Code Playgroud)
唯一需要注意的是,在某些平台(例如,macOS)上,\t不支持转义序列,因此需要使用文字制表符char.必须使用ANSI quoting($'\t')拼接到命令字符串中:
sed 's/'$'\t''/,/g' file.tsv > file.csv
Run Code Online (Sandbox Code Playgroud)
awk:
需要注意的awk是FS- 输入字段分隔符 - 必须设置为\t 显式 - 否则默认行为将剥离前导和尾随选项卡,并仅使用单个选项卡替换多个选项卡的内部跨度,:
awk 'BEGIN { FS="\t"; OFS="," } {$1=$1; print}' file.tsv > file.csv
Run Code Online (Sandbox Code Playgroud)
请注意,简单地分配$1给自身会导致awk使用OFS- 输出字段分隔符重建输入行; 这有效地取代了所有的\t角色.与,chars.print然后只需打印重建线.
强大的awk解决方案:
正如A. Rabus指出的那样,上述解决方案不处理本身,正确包含字符的未加引号的输入字段- 您最终会得到额外的CSV字段.
以下awk解决方案通过"..."按需封装这些字段来修复此问题(请参阅awk上面的非强健解决方案以获得该方法的部分解释):
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
Run Code Online (Sandbox Code Playgroud)
"检测包含""但未包含在双引号中的任何字段
$i ~ /[,"]/ && $i !~ /^".*"$/ 通过用双引号括起来更新字段
如前所述,更新任何电场使,以重建从领域的线与所述"值,即,gsub("\"", "\"\"", $i)在这种情况下,这相当于有效的TSV - > CSV转换; flag "用于确保每个输入记录至少重建一次.