如何使用Perl修改CSV文件中的字段?

时间:2009-11-24 10:34:38

标签: perl csv

我有一个包含以下示例数据的csv文件。

o-option(alphabetical)
v-value(numerical)

number1,o1,v1,o2,v2,o3,v3,o4,v4,o5,v5,o6,v6
number2,o1,v11,o2,v22,o3,v33,o44,v44,o5,v55,o6,v66

and so on....

必需的输出。

NUM,o1,o2,o3,o4,o44,o5,o6
number1,v1,v2,v3,v4,,v5,v6
number2,v11,v22,v33,,v44,v55,v66

and so on...

在这个数据中,所有选项都是相同的,即o1,o2等在整个文件中,但是选项4的值正在改变,即o4,o44等。总共在o4字段有大约9个不同的选项值。任何人都可以帮我使用perl代码来获得所需的输出。

我编写了以下代码,但仍未获得所需的输出。

my @values;
my @options;
my %hash;

while (<STDIN>) {
chomp;
my ($srn,$o1,$v1,$o2,$v2,$o3,$v3,$o4,$v4,$o5,$v5,$o6,$v6) = split /[,\n]/, $_;
push @values, [$srn,$v1,$v2,$v3,$v4,$v5,$v6];
push @options, $o1,$o2,$o3,$o4,$o5,$o6;
}

#printing the header values
my @out = grep(!$hash{$_}++,@options);
print 'ID,', join(',', sort @out), "\n";

#printing the values.
for my $i ( 0 .. $#values) {
        print @{$values[$i]}, "\n";
}

输出:

ID,o1,o2,o3,o4,o44,o5,o6
number1,v1,v2,v3,v4,v5,v6
number2,v1,v2,v3,v44,v5,v6

从上面的输出中,当值44到来时,它来自option4,因此其他值向左移动。值未与选项映射。请建议。

4 个答案:

答案 0 :(得分:2)

如果要根据前面的选项值的值在列中按行排列数值,请将数据行存储为哈希值,并使用选项作为哈希值的键。

use strict;
use warnings;

my (@data, %all_opts);

while (<DATA>) {
    chomp;
    my %h = ('NUM', split /,/, $_);
    push @data, \%h;
    @all_opts{keys %h} = 1;
}

my @header = sort keys %all_opts;
print join(",", @header), "\n";

for my $d (@data){
    my @vals = map { defined $d->{$_} ? $d->{$_} : '' } @header;
    print join(",", @vals), "\n";    
}


__DATA__
number1,o1,v1,o2,v2,o3,v3,o4,v4,o5,v5,o6,v6
number2,o1,v11,o2,v22,o3,v33,o44,v44,o5,v55,o6,v66

答案 1 :(得分:1)

这就是你要追求的吗?

use strict;
use warnings;
use 5.010;

my %header;
my @store;

while (<DATA>) {
    chomp;
    my ($srn, %f) = split /,/;
    @header{ keys %f } = 1;
    push @store, [ $srn, { %f } ];
}

# header
my @cols = sort keys %header;
say join q{,} => 'NUM', @cols;

# rows
for my $row (@store) {
    say join q{,} => $row->[0], 
                     map { $row->[1]->{ $_ } || q{} } @cols;
}

__DATA__
number1,o1,v1,o2,v2,o3,v3,o4,v4,o5,v5,o6,v6
number2,o1,v11,o2,v22,o3,v33,o44,v44,o5,v55,o6,v66

哪个输出:

NUM,o1,o2,o3,o4,o44,o5,o6 
number1,v1,v2,v3,v4,,v5,v6
number2,v11,v22,v33,,v44,v55,v66

答案 2 :(得分:0)

通过文件传递一个标识所有不同选项值的文件,构建这些值的数组。

第二次通过文件:

for each record
    initialise an associative array from your list of option value
    parse the assigning values for the options you have
    use your list of option values to iterate the associative array printing the values 

答案 3 :(得分:0)

您可以查看CPAN模块DBD::AnyData。其中一个更整洁的模块。它允许您像操作数据库一样操作CSV文件。还有更多。