我正在处理大量CSV文件,并且在其中一列中,字段本身包含逗号。不幸的是,此列没有用引号引起来,因此将CSV文件加载到外部应用程序中会引起问题。
我的CSV文件如下:
col1, col2, col3, co,,,l4, col5, col6
col1, col2, col3, co,,,,,l4, col5, col6
col1, col2, col3, co,,l4, col5, col6
我需要删除此特定列中的所有逗号,但是我不确定如何去做。不幸的是,用正确地用引号引起来的有问题的列重写文件不是一种选择。
这些有问题的逗号总是在 倒数第二个逗号之间出现,但是我没有足够的bash专业知识来编写删除它们的脚本。
输入文件:
col1, col2, col3, co,,,l4, col5, col6
col1, col2, col3, co,,,,,l4, col5, col6
col1, col2, col3, co,,l4, col5, col6
预期输出:
col1, col2, col3, col4, col5, col6
col1, col2, col3, col4, col5, col6
col1, col2, col3, col4, col5, col6
答案 0 :(得分:0)
我会提出以下建议:
awk '{ match($0,/^[^,]*,[^,]*,[^,],/); p1=RLENGTH+1
match($0,/,[^,]*,[^,]*$/); ; p2=RSTART
s=substr($0,p1,p2-p1); gsub(/,/,"",s)
print substr($0,1,p1-1) s substr($0,p2)
}' file.csv
或
awk 'BEGIN{FS=OFS=","}
{ s=""; for(i=4;i<NF-1;++i) s=s $i }
{ print $1,$2,$3,s,$(NF-1),$NF }' file.csv
这些解决方案假定col1,col2,col3,col5和col6中没有出现,
。
如果其他列中有逗号,但根据CSV标准正确引用了这些列,则可以使用基于What's the most robust way to efficiently parse CSV using awk?
的类似方法awk -v FPAT='[^,]*|"[^"]+"' 'BEGIN{OFS=","}
{ s=""; for(i=4;i<NF-1;++i) s=s $i }
{ print $1,$2,$3,s,$(NF-1),$NF }' file.csv
更一般地,回答标题问题:
如何替换该字符的第N个和第K个最后一个实例之间的所有字符实例?
假设c
是字符:
awk 'BEGIN{FS=OFS="c"; n=3; k=}
{ s=""; for(i=1; i <= n ;++i) s = $i OFS
for( ; i <= NF-k;++i) s=s $i
for( ; i <= NF ;++i) s = OFS $i }
{ print s }' file.csv
答案 1 :(得分:0)
如果您真的只想删除该字段中的逗号,则使用GNU awk将第三个参数匹配():
awk 'match($0,/(([^,]*,){3})(.*)((,[^,]*){2})/,a){gsub(/,/,"",a[3]); $0=a[1] a[3] a[4]} 1' file
col1, col2, col3, col4, col5, col6
col1, col2, col3, col4, col5, col6
col1, col2, col3, col4, col5, col6
,否则我将麻烦的字段用双引号引起来,然后将其像其他CSV一样对待(例如,参见What's the most robust way to efficiently parse CSV using awk?):
$ awk 'match($0,/(([^,]*,){3})(.*)((,[^,]*){2})/,a){$0=a[1] "\"" a[3] "\"" a[4]} 1' file
col1, col2, col3," co,,,l4", col5, col6
col1, col2, col3," co,,,,,l4", col5, col6
col1, col2, col3," co,,l4", col5, col6
$ awk '
BEGIN { FPAT="[^,]*|\"[^\"]+\"" }
match($0,/(([^,]*,){3})(.*)((,[^,]*){2})/,a) { $0=a[1] "\"" a[3] "\"" a[4] }
{ for (i=1; i<=NF; i++) print NR, NF, i, $i }
' file
1 6 1 col1
1 6 2 col2
1 6 3 col3
1 6 4 " co,,,l4"
1 6 5 col5
1 6 6 col6
2 6 1 col1
2 6 2 col2
2 6 3 col3
2 6 4 " co,,,,,l4"
2 6 5 col5
2 6 6 col6
3 6 1 col1
3 6 2 col2
3 6 3 col3
3 6 4 " co,,l4"
3 6 5 col5
3 6 6 col6
或只是用sed引用部分:
$ sed -E 's/(([^,]*,){3})(.*)((,[^,]*){2})/\1"\3"\4/' file
col1, col2, col3," co,,,l4", col5, col6
col1, col2, col3," co,,,,,l4", col5, col6
col1, col2, col3," co,,l4", col5, col6
以上要求-E
使用GNU或BSD / OSX。对于任何POSIX sed,它都是:
$ sed 's/\(\([^,]*,\)\{3\}\)\(.*\)\(\(,[^,]*\)\{2\}\)/\1"\3"\4/' file
col1, col2, col3," co,,,l4", col5, col6
col1, col2, col3," co,,,,,l4", col5, col6
col1, col2, col3," co,,l4", col5, col6