我的 sed
技能不是很好,所以我不确定如何处理这样一行文本
1,2,"12,345",x,y,"a,b"
把它转化为
1,2,12345,x,y,"a,b"
因此,数字"12,345"变成了12345,但"a,b"保持不变。
如果数值是数字,我需要以某种方式保留逗号周围的值。我有一个想法,关于如何只处理数字,但不确定如何仅删除逗号,而不是整列。
我的 sed
技能不是很好,所以我不确定如何处理这样一行文本
1,2,"12,345",x,y,"a,b"
1,2,12345,x,y,"a,b"
因此,数字"12,345"变成了12345,但"a,b"保持不变。
如果数值是数字,我需要以某种方式保留逗号周围的值。我有一个想法,关于如何只处理数字,但不确定如何仅删除逗号,而不是整列。
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"
To make in-place changes you can use -i
option or re-direct the output to another file.
#!/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 $!;
在一个正则表达式替换中,你可以做一些像这样恶心的事情:
/\G(?|(")(\d+)(?:,(\d+))*(")|()([^,]+)()())(,|$)/g
用以下内容替换:
\1\2\3\4\5
这应该在Perl中可以很好地工作。
您可以使用:
echo '1,2,"12,345",x,y,"a,b"' | sed 's/"\([0-9]*\),\([0-9]*\)"/\1\2/g'
编辑:实际上,我的解决方案仅在双引号之间只有一个逗号的情况下有效。