1

我在 CSV 文件中有一堆数据,第一行是所有字符串(所有文本和下划线),所有后续行都填充了与所述字符串相关的数字。

我试图解析第一行并找到特定的字符串,记住该字符串所在的列,然后遍历文件的其余部分并获取同一列中的数据。我需要对三个字符串执行此操作。

我一直在使用 Text::CSV 但我不知道如何让它增加一个计数器,直到它在第一行找到字符串然后转到下一行,从同一列获取数据等. 等等 这是我迄今为止尝试过的:

while (<CSV>) {
    if ($csv->parse($data)) {
        my @field = $csv->fields;
        my $count = 0;
            for $column (@field) {
            print ++$count, " => ", $column, "\n";
        }
    } else {
        my $err = $csv->error_input;
        print "Failed to parse line: $err";
    }
}

由于 $data 在第 1 行,它会打印 25 次“1 $data”(CSV 文件中的行数)。我如何让它记住它在哪一列中找到了 $data?另外,因为我知道所有字符串都在第 1 行,我如何让它只解析第 1 行,找到 @data 中的所有字符串,然后解析文件的其余部分,从必要的列并将其放入矩阵或数组数组中?
谢谢您的帮助!

编辑:我意识到我的问题措辞有点糟糕。我不知道如何从 CSV 获取列号。这是怎么做到的?
另外,一旦我得到了列号,我如何告诉它 CSV 遍历后续行并仅从该列中获取数据?

4

2 回答 2

0

尝试这样的事情:

use strict;
use warnings;
use Text::CSV;

my $csv = Text::CSV->new({binary=>1});

my $thing_to_match = "blah";
my $matched_index;
my @stored_data = ();

while(my $row= $csv->getline(*DATA)) #grabs lines below __DATA__ 
                                     #(near the end of the script)
{
    my @fields = @$row;

    #If we haven't found the matched index, yet, search for it.
    if(not defined $matched_index)
    {
        foreach my $i(0..$#fields)
        {
            $matched_index = $i if($fields[$i] eq $thing_to_match);
        }
    }

    #NOTE: We're pushing a *reference* to an array!
    #Look at perldoc perldata
    push @stored_data,\@fields;
}

die "Column for '$thing_to_match' not found!" unless defined $matched_index;

foreach my $row(@stored_data)
{
    print $row->[$matched_index] . "\n";
}


__DATA__
stuff,more stuff,yet more stuff
"yes, this thing, is one item",blah,blarg
1,2,3

输出是:

more stuff
blah
2
于 2013-02-07T20:48:39.230 回答
0

我没有时间写一个完整的例子,但我写了一个可以帮助你做到这一点的模块。Tie::Array::CSV使用了一些魔法来让你的 csv 文件表现得像 Perl 的 arrayrefs 数组。通过这种方式,您可以使用您的 Perl 知识与文件进行交互。

一句警告的话!我的模块的一个好处是它是读/写的。由于您只想阅读,请注意不要分配给它!

于 2013-02-07T21:49:24.557 回答