使用perl向CSV添加引号

时间:2016-10-22 18:51:55

标签: regex perl replace

我的CSV看起来如下:

A,01,ALPHA
00,D,CHARLIE
E,F,02

这是转换后所需的文件:

"A",01,"ALPHA"
00,"D","CHARLIE"
"E","F",02

如您所见,完全数字的字段不加引号,而引用alpha(或字母数字)。

在Perl中解决这个问题的合理方法是什么?

下面已经评论过了,但我已尝试过像

这样的内容
perl -pe 's/(\w+)/"$1"/g'

这并不起作用,因为\ w显然会接受数字。

3 个答案:

答案 0 :(得分:5)

我建议不要重新发明轮子,而是像zdim推荐的那样使用现有的模块。以下是使用Text::CSV_XS

的示例

<强> test.pl

#!/usr/bin/env perl

use warnings;
use strict;

use Text::CSV_XS;
use Scalar::Util qw( looks_like_number );

my $csv = Text::CSV_XS->new();
while (my $row = $csv->getline(*STDIN)) {
    my @quoted_row = map { looks_like_number($_) ? $_ : '"'. $_ .'"' } @$row;
    print join(',',@quoted_row) . "\n";
}

<强>输出

cat input | perl test.pl
"A",01,"ALPHA"
00,"D","CHARLIE"
"E","F",02

答案 1 :(得分:1)

好像你是在追逐一个班轮。这是一个基本的

perl -lpe '$_ = join ",", map /^\d+$/ ? $_ : "\"$_\"", split ",";' input.csv

,拆分每一行,并将获得的列表传递给map。每个元素仅针对仅数字/^\d+$/进行测试并且不受影响地传递,否则使用"填充。然后map返回,的返回。

-l删除换行符,自"填充整行后需要的内容。结果已分配回$_,以便能够使用-p,因此无需显式打印。

如果你不坚持使用单行代码,代码很容易在脚本中使用。

模块可以更好地处理csv文件,例如Text::CSV

答案 2 :(得分:1)

修改了另一个单行输入文件以添加带字母数字字段的行

$ cat ip.csv 
A,01,ALPHA
00,D,CHARLIE
E,F,02
23,AB12,53C

$ perl -F, -lane 's/.*[^0-9].*/"$&"/ foreach(@F); print join ",", @F' ip.csv 
"A",01,"ALPHA"
00,"D","CHARLIE"
"E","F",02
23,"AB12","53C"


要修改OP的尝试:

$ perl -pe 's/(^|,)\K\d+(?=,|$)(*SKIP)(*F)|\w+/"$&"/g' ip.csv 
"A",01,"ALPHA"
00,"D","CHARLIE"
"E","F",02
23,"AB12","53C"
  • (^|,)\K\d+(?=,|$)(*SKIP)(*F)这将跳过仅包含数字的字段,替换模式\w+将被替换