我sed
非常不稳定,所以我不确定怎么排这样的
1,2,"12,345",x,y,"a,b"
并将其转换为
1,2,12345,x,y,"a,b"
所以数字" 12,345"变为12345,但" a,b"保持不变。
当值为数字时,我需要以某种方式保留逗号周围的值。我知道正则表达式如何只处理数字,但不确定如何删除逗号,而不是删除整个列。
答案 0 :(得分:2)
解析CSV应该使用正确的csv解析器。我也会推荐perl
。
perl -MText::ParseWords -ne '
@line = parse_line(",", 1, $_);
print join "," , map { s/,//g if $_ =~ /^[0-9,"]+$/; $_ } @line
' text.csv
$ cat text.csv
1,2,"12,345",x,y,"a,b"
"a,c","12,345",x,y,"a,b"
$ perl -MText::ParseWords -ne '
@line = parse_line(",", 1, $_);
print join "," , map { s/,//g if $_ =~ /^[0-9,"]+$/; $_ } @line
' text.csv
1,2,"12345",x,y,"a,b"
"a,c","12345",x,y,"a,b"
要进行就地更改,您可以使用-i
选项或将输出重定向到另一个文件。
答案 1 :(得分:1)
Perl解决方案,使用Text::CSV:
#!/usr/bin/perl
use warnings;
use strict;
use Text::CSV;
my @rows;
my $csv = 'Text::CSV'->new({ binary => 1}) or die 'Text::CVS'->error_diag;
open my $IN, '<', 'file.csv' or die $!;
while (my $row = $csv->getline($IN)) {
for my $cell (@$row) {
$cell =~ s/,// if $cell =~ /^[0-9,]+$/;
}
push @rows, $row;
}
$csv->eof or $csv->error_diag;
open my $OUT, '>', 'new.csv' or die $!;
$csv->print($OUT, $_) for @rows;
close $OUT or die $!;
答案 2 :(得分:1)
在一个正则表达式替换中,你可以做一些令人讨厌的事情:
/\G(?|(")(\d+)(?:,(\d+))*(")|()([^,]+)()())(,|$)/g
用。。。来代替
\1\2\3\4\5
这应该可以与Perl一起使用。
答案 3 :(得分:0)
您可以使用:
echo '1,2,"12,345",x,y,"a,b"' | sed 's/"\([0-9]*\),\([0-9]*\)"/\1\2/g'
编辑:实际上,只有在双引号之间插入一个逗号时,我的解决方案才有效。
答案 4 :(得分:0)
使用此模式(\d),(\d)(?!(([^"]*"){2})*[^"]*$)
并替换w / $1$2
Demo