![逗号分隔文件的值中包含逗号](https://linux22.com/image/211582/%E9%80%97%E5%8F%B7%E5%88%86%E9%9A%94%E6%96%87%E4%BB%B6%E7%9A%84%E5%80%BC%E4%B8%AD%E5%8C%85%E5%90%AB%E9%80%97%E5%8F%B7.png)
我有一个包含数据的文件,如下所示:
“A”,”Dept1”,”i am mahesh,working in it”,”1”
“B”,”Dept2”,”i am suresh, working in non it”,”2”
我想要的输出是:
A,Dept1,i am mahesh~working in it,1
B,Dept2,i am suresh~working in non it,2
我在下面尝试过,但它正在用 ~ 替换 all , 如下所示:
awk -F ‘“,”’ -v OFS=‘’ ‘{for (i=0;i<=NF;++i) gsub(“,”,”~”,$i)}1’ file
“A”~”Dept1”~”i am mahesh~working in it”~”1”
“B”~”Dept2”~”i am suresh~working in non it”~”2”
答案1
使用结构化文档格式时,请使用了解该特定格式的工具,而不是通用文本处理工具。
在 CSV 文件中,除非已知它“简单”,否则引用的字段可能包含逗号和换行符。带引号的字段中的引号会加倍 ( ""
)。
要将嵌入的逗号更改为波形符 ( ~
),最好使用支持 CSV 的工具,例如MLR(米勒)或csvkit。
下面,我假设引号字符是普通的双引号 ( "
),而不是您在问题文本中使用的大引号 ( ”
)。
这是用 来转换第三个字段mlr
,这是一个方便的工具,可以识别几种不同的结构化格式:
$ mlr --csv -N put '$3=sub($3,",","~")' file
A,Dept1,i am mahesh~working in it,1
B,Dept2,i am suresh~ working in non it,2
该--csv
选项导致mlr
输入和输出 CSV 数据,并-N
告诉实用程序我们的数据没有标题。然后,我们应用put
“动词”(动作)并给它一个如果您习惯的话应该看起来很熟悉的表达式awk
(尽管参数的顺序sub()
不同)。
使用csvformat
(来自 csvkit),我们可以重新格式化数据,以便我们可以更轻松地找到我们想要更改的逗号。
我首先将分隔符更改为@
(尚未属于数据的任何字符):
$ csvformat -D '@' file
A@Dept1@i am mahesh,working in it@1
B@Dept2@i am suresh, working in non it@2
然后我可以简单地使用tr
将剩余的逗号更改为波形符:
$ csvformat -D '@' file | tr ',' '~'
A@Dept1@i am mahesh~working in it@1
B@Dept2@i am suresh~ working in non it@2
然后再次使用以下命令将分隔符切换回逗号csvformat
:
$ csvformat -D '@' file | tr ',' '~' | csvformat -d '@'
A,Dept1,i am mahesh~working in it,1
B,Dept2,i am suresh~ working in non it,2
请注意,这会改变全部嵌入逗号到波形符,而不仅仅是第三列中的逗号。
将结果重定向到新名称以将其保存到文件中。
答案2
尝试sed
a) 将双引号之间出现的所有逗号 NOT 更改为波形符,然后 b) 删除所有双引号:
sed 's/\([^"]\),\([^"]\)/\1~\2/g;s/"//g' infile
如果结果良好,则用于-i
就地替换文件。
假设是全部字段在使用前用引号引起来。