我的 csv 文件有问题,需要添加一些引号
在
field,field2,text field with potential commas,field4,field5
field,field2,text fie,ld with pot,ential commas,field4,field5
field,field2,text field with, potential commas,field4,field5
出去
field,field2,"text field with potential commas",field4,field5
field,field2,"text fie,ld with pot,ential commas",field4,field5
field,field2,"text field with, potential commas",field4,field5
sed 's/,/,"/2'
将添加第一个引号,但是我如何对每行从末尾向后的第二次出现执行相同的操作?
欢迎使用 sed、awk、perl 等方法。文件有几百万行,速度值得赞赏。
答案1
这是一种awk
方法:如果有超过五个逗号分隔字段,则循环遍历连接它们的“中间”字段,然后打印用引号括起来的新字段,然后打印最后两个字段:
awk -f awkscript.awk < input
如下awkscript.awk
:
BEGIN {
OFS=","
FS=","
}
{
if (NF > 5) {
middle=""
for(i=3; i <= NF-2; i++)
middle=(middle ? middle"," : "")$i
print $1, $2, "\""middle"\"", $(NF-1), $NF
} else {
print $1, $2, "\""$3"\"", $4, $5
}
}
答案2
使用sed
你会这样做:
sed 's/,/,"/2; s/\(,[^,]*,[^,]*\)$/"\1/' infile
这s/,/,"/2
仅取代第二个。这从行尾作为与反向引用的组匹配s/\(,[^,]*,[^,]*\)$
进行匹配,然后在添加引号后的替换部分中我们将其带回,anything-not-a-comma,anything-not-a-comma
$
\1
"\1
答案3
这是一个非常简单的方法,尽管可能不是最有效的:
sed 's/,/,"/2' input.csv | rev | sed 's/,/,"/2' | rev > output.csv
答案4
sed -e '
s/,/&\n/2
s/\n\(.*\)\(,.*,.*\)/"\1"\2/
' input.csv
perl -pe '
my $p;
while ( /,/g ) {
s/\G/"/,next if ++$p == 2;
last if s/,\G(?=.*,)(?!.*,.*,)/",/; # looks for 2nd last comma
}
' input-file.csv
perl -pe '
substr($_, index($_, q/,/, 1+index($_, q/,/)), 1) = q/,"/;
substr($_, rindex($_, q/,/, -1+rindex($_, q/,/)), 1) = q/",/;
' csvfile
这里我们调用索引函数两次来获取左侧第二个逗号的位置。现在位置已经确定,然后使用 substr 函数在其旁边放置一个引号。
同样,我们调用rindex函数并进行相应的更改。