如何在BASH中将制表符分隔值(TSV)文件转换为逗号分隔值(CSV)文件?(How do I convert a tab-separated values (TSV) file to a comma-separated values (CSV) file in BASH?)
我有一些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?)的更多相关文章
- 字符串 CSV解析 表格 逗号分隔值 通讯录 电话簿 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- excel保存为制表符分隔的文本文件 js无法完整读取
excel保存为制表符分隔的文本文件 js无法完整读取 excel另存为文本有两个选项,一个是制表符分隔的文本文件,一个是unicode文本.生成的文件Unicode更大一些.但是这里需要注意的是[制 ...
- 如何在 Go 中将 []byte 转换为 io.Reader?
原文链接: 如何在 Go 中将 []byte 转换为 io.Reader? 在 stackoverflow 上看到一个问题,题主进行了一个网络请求,接口返回的是 []byte.如果想要将其转换成 io ...
- 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 ...
- 如何在js中将统计代码图标隐藏
建站时我们都会加一下网站统计,方便把控内容的内容的运营.大部分站长安装的站点统计是第三方统计代码,js形式的,很少用以服务器日志为基础分析的统计.(当然能通过网站日志来分析网站的运营者比一般的站长水平 ...
- 如何在 WPF 中获取所有已经显式赋过值的依赖项属性
原文:如何在 WPF 中获取所有已经显式赋过值的依赖项属性 获取 WPF 的依赖项属性的值时,会依照优先级去各个级别获取.这样,无论你什么时候去获取依赖项属性,都至少是有一个有效值的.有什么方法可以获 ...
- C#对.CSV格式的文件--逗号分隔值文件 的读写操作及上传ftp服务器操作方法总结
前言 公司最近开发需要将数据保存到.csv文件(逗号分隔值 文件)中然后上传到ftp服务器上,供我们系统还有客户系统调用,之前完全没有接触过这个,所以先来看看百度的解释:逗号分隔值(Comma-Sep ...
- 微软BI 之SSIS 系列 - 在 SSIS 中将指定目录下的所有文件分类输出到不同文件夹
开篇介绍 比如有这样的一个需求,旧的一个业务系统通常将产出的文件输出到同一个指定的目录下的不同子目录,输出的文件类型有 XML,EXCEL, TXT 这些不同后缀的文件.现在需要在 SSIS 中将它们 ...
- test命令用法。功能:检查文件和比较值
test命令用法.功能:检查文件和比较值 1)判断表达式 if test (表达式为真) if test !表达式为假 test 表达式1 –a 表达式2 两个表达 ...
- CSV (逗号分隔值文件格式)
逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本).纯文本意味着该文件是一个字符序列,不 ...
随机推荐
- 对抗生成网络(GAN)简单介绍
对抗生成网络主要由生成网络和判别网络构成,GAN在图像领域使用较多.利用生成网络生成假的图像,然后利用判别器是否能判断该图像是假的. 1.用于医学图像分割,一般我们可以利用一个U-Net网络生成分割结 ...
- 如何使用echarts
官网:https://echarts.apache.org/handbook/zh/get-started/ a 下载js文件并引入 b 初始化实例对象 echarts.init(获取盒子对象) 关 ...
- KubeSphere 社区双周报| 2024.08.30-09.12
KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书.新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列 ...
- 在 openEuler 22.03 上安装 KubeSphere 实战教程
作者:老 Z,中电信数智科技有限公司山东分公司运维架构师,云原生爱好者,目前专注于云原生运维,云原生领域技术栈涉及 Kubernetes.KubeSphere.DevOps.OpenStack.Ans ...
- Top100(中)
Top100(中) 二叉树 94. 二叉树的中序遍历 int *res; void inorder(struct TreeNode *root, int *returnSize) { if (root ...
- rqt的安装及详细介绍
1. 安装 安装极其简单,不多介绍,直接上命令:Melodic: sudo apt-get install ros-melodic-rqt sudo apt-get install ros-melod ...
- 栈与队列(c语言实现)
文章目录 1.栈 1.1基于数组实现栈 1.1.1定义栈的结构体 1.1.2栈的初始化 1.1.3栈的释放 1.1.4元素入栈 1.1.5元素出栈 1.1.6访问栈顶元素 1.2基于链表实现栈 1.2 ...
- MySQL查询BLOB类型的字段
1.MySQL有四种BLOB类型: 1.TinyBlob 最大能容纳255B的数据 2.Blob 最大能容纳65KB的 3.MediumBlob 最大能容纳16MB的数据 4.LongBlob 最大能 ...
- 初识GO语言--高级数据类型
- 对于特定的游戏问题使用启发式算法可以取得比AI算法更好的表现
相关: Using A.I. to DOMINATE NERDS in TETRIS 有些问题的求解可以通过建模将其转换为强化学习问题,然后再使用强化学习算法对其进行求解,但是很多问题如果不建模为强化 ...