我有一些TSV文件需要转换为CSV文件. BASH中是否有任何解决方案,例如使用awk来转换这些?我可以这样使用sed,但担心它会出错:

sed 's/\t/,/g' file.tsv > file.csv
  • 不需要添加行情.

如何将TSV转换为CSV?

解决方案

更新:尽管以下解决方案总体上不可靠 在OP的特定用例中进行工作;请参见底部部分,以获取基于awk的可靠解决方案.


总结选项(有趣的是,它们的表现大致相同):

tr :

devnull的解决方案(在问题注释中提供)是最简单的:

tr '\t' ',' < file.tsv > file.csv

固定:

OP自己的sed解决方案非常好,因为输入不包含带引号的字符串(可能嵌入了\t字符.):

sed 's/\t/,/g' file.tsv > file.csv

唯一需要注意的是,在某些平台(例如macOS)上,不支持转义序列\t,因此使用文字制表符char.必须使用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- output 字段分隔符重建输入行;这有效地替换了所有\t字符.与,字符. print然后简单地打印重建的行.


强大的awk解决方案:

A. Rabus指出,以上解决方案无法正确处理本身包含,字符的未加引号的输入字段-您最终将获得额外的CSV字段.

下面的awk解决方案通过按需将这些字段包含在"..."中来解决此问题(有关该方法的部分说明,请参见上面的非稳健的awk解决方案).

如果此类字段也嵌入了"字符,则会按照RFC 4180.谢谢,怀亚特以色列.

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用于确保至少一次重新构建每个输入记录.

I have some TSV files that I need to convert to CSV files. Is there any solution in BASH, e.g. using awk, to convert these? I could use sed, like this, but am worried it will make some mistakes:

sed 's/\t/,/g' file.tsv > file.csv
  • Quotes needn't be added.

How can I convert a TSV to a CSV?

解决方案

Update: The following solutions are not generally robust, although they do work in the OP's specific use case; see the bottom section for a robust, awk-based solution.


To summarize the options (interestingly, they all perform about the same):

tr:

devnull's solution (provided in a comment on the question) is the simplest:

tr '\t' ',' < file.tsv > file.csv

sed:

The OP's own sed solution is perfectly fine, given that the input contains no quoted strings (with potentially embedded \t chars.):

sed 's/\t/,/g' file.tsv > file.csv

The only caveat is that on some platforms (e.g., macOS) the escape sequence \t is not supported, so a literal tab char. must be spliced into the command string using ANSI quoting ($'\t'):

sed 's/'$'\t''/,/g' file.tsv > file.csv

awk:

The caveat with awk is that FS - the input field separator - must be set to \t explicitly - the default behavior would otherwise strip leading and trailing tabs and replace interior spans of multiple tabs with only a single ,:

awk 'BEGIN { FS="\t"; OFS="," } {$1=$1; print}' file.tsv > file.csv

Note that simply assigning $1 to itself causes awk to rebuild the input line using OFS - the output field separator; this effectively replaces all \t chars. with , chars. print then simply prints the rebuilt line.


Robust awk solution:

As A. Rabus points out, the above solutions do not handle unquoted input fields that themselves contain , characters correctly - you'll end up with extra CSV fields.

The following awk solution fixes this, by enclosing such fields in "..." on demand (see the non-robust awk solution above for a partial explanation of the approach).

If such fields also have embedded " chars., these are escaped as "", in line with RFC 4180.Thanks, 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 !~ /^".*"$/ detects any field that contains , and/or " and isn't already enclosed in double quotes

  • gsub("\"", "\"\"", $i) escapes embedded " chars. by doubling them

  • $i = "\"" $i "\"" updates the result by enclosing it in double quotes

  • As stated before, updating any field causes awk to rebuild the line from the fields with the OFS value, i.e., , in this case, which amounts to the effective TSV -> CSV conversion; flag rebuilt is used to ensure that each input record is rebuilt at least once.

如何在BASH中将制表符分隔值(TSV)文件转换为逗号分隔值(CSV)文件?(How do I convert a tab-separated values (TSV) file to a comma-separated values (CSV) file in BASH?)的更多相关文章

  1. 字符串 CSV解析 表格 逗号分隔值 通讯录 电话簿 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. excel保存为制表符分隔的文本文件 js无法完整读取

    excel保存为制表符分隔的文本文件 js无法完整读取 excel另存为文本有两个选项,一个是制表符分隔的文本文件,一个是unicode文本.生成的文件Unicode更大一些.但是这里需要注意的是[制 ...

  3. 如何在 Go 中将 []byte 转换为 io.Reader?

    原文链接: 如何在 Go 中将 []byte 转换为 io.Reader? 在 stackoverflow 上看到一个问题,题主进行了一个网络请求,接口返回的是 []byte.如果想要将其转换成 io ...

  4. linux bash脚本把A和B文件中有相同ID的B文件的内容输出到文件C

    bash脚本把A和B文件中有相同ID的B文件的内容输出到文件C. Aid文件:ID001.1ID032.1ID090.10 Bfilt文件:XX XX XXX ID001.1 XXX999999999 ...

  5. 如何在js中将统计代码图标隐藏

    建站时我们都会加一下网站统计,方便把控内容的内容的运营.大部分站长安装的站点统计是第三方统计代码,js形式的,很少用以服务器日志为基础分析的统计.(当然能通过网站日志来分析网站的运营者比一般的站长水平 ...

  6. 如何在 WPF 中获取所有已经显式赋过值的依赖项属性

    原文:如何在 WPF 中获取所有已经显式赋过值的依赖项属性 获取 WPF 的依赖项属性的值时,会依照优先级去各个级别获取.这样,无论你什么时候去获取依赖项属性,都至少是有一个有效值的.有什么方法可以获 ...

  7. C#对.CSV格式的文件--逗号分隔值文件 的读写操作及上传ftp服务器操作方法总结

    前言 公司最近开发需要将数据保存到.csv文件(逗号分隔值 文件)中然后上传到ftp服务器上,供我们系统还有客户系统调用,之前完全没有接触过这个,所以先来看看百度的解释:逗号分隔值(Comma-Sep ...

  8. 微软BI 之SSIS 系列 - 在 SSIS 中将指定目录下的所有文件分类输出到不同文件夹

    开篇介绍 比如有这样的一个需求,旧的一个业务系统通常将产出的文件输出到同一个指定的目录下的不同子目录,输出的文件类型有 XML,EXCEL, TXT 这些不同后缀的文件.现在需要在 SSIS 中将它们 ...

  9. test命令用法。功能:检查文件和比较值

    test命令用法.功能:检查文件和比较值 1)判断表达式 if test  (表达式为真) if test !表达式为假 test 表达式1 –a 表达式2                  两个表达 ...

  10. CSV (逗号分隔值文件格式)

    逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本).纯文本意味着该文件是一个字符序列,不 ...

随机推荐

  1. git 设置代理和取消代理

    1.设置代理 git config --global http.proxy "127.0.0.1:1080" 2.取消代理 git config --global --unset ...

  2. 深度学习 - Torch-TensorRT 推理加速

    深度学习 - Torch-TensorRT 推理加速 Torch-TensorRT 作为 TorchScript 的扩展. 它优化并执行兼容的子图,让 PyTorch 执行剩余的图. PyTorch ...

  3. 将数组数据转化成树形结构 tranListToTreeData

    export function tranListToTreeData(list, rootValue) { // list是最完整的数组 let arr = []; // 记录儿子 list.forE ...

  4. python实现链表(单链,双链)

    # code:utf-8 # createTime:2023.8.17 # -------------------------------------------------------------- ...

  5. Linux查看CPU核数

    **方法一:通过proc文件系统 获取cpu总数量 命令如下 ** cat /proc/cpuinfo |grep processor 方法二:nproc命令 nproc 方法三:lscpu 显示CP ...

  6. 使用 KubeSphere 和极狐GitLab 打造云原生持续交付系统

    KubeSphere 简介 Kubernetes 是一个非常复杂的容器编排平台,学习成本非常高,KubeSphere 所做的事情就是高度产品化和抽象了底层 Kubernetes,是一个面向云原生的操作 ...

  7. 带你玩转nginx负载均衡

    nginx跨多个应用程序实例的负载平衡是一种用于优化资源利用率,最大化吞吐量,减少延迟和确保容错配置的常用技术. 环境介绍 配置nginx负载均衡器因会用到多台服务器来进行,所以下面我会用到docke ...

  8. mysql文本数据导入

    MySQL使用mysqlimport命令导入文本文件 MySQL中,可以使用mysqlimport命令将文本文件导入到MySQL数据库中.基本的语法格式如下: mysqlimport <dbna ...

  9. 了解 Uniswap V2(DEX)

    Uniswap V2 是一个基于以太坊的去中心化交易所(DEX),它通过流动性池和自动化做市商(AMM)模型来实现去中心化的代币交换.以下是 Uniswap V2 的核心概念: 1. 自动化做市商(A ...

  10. Redis学习笔记整理

    一.Redis概述 1.redis简介 Redis(REmote DIctionary Server 远程字典服务器)是一款开源的,用ANSI C编写.支持网络.基于内存.亦可持久化的日志型.Key- ...