我在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行,它打印“1 $ data”25次(CSV文件中的行数)。如何让它记住它找到$ data的列?此外,由于我知道所有字符串都在第1行,我如何让它只通过第1行解析,找到@data中的所有字符串,然后解析文件的其余部分,从必要的数据中获取数据列并将其放入矩阵或数组数组中? 谢谢你的帮助!
编辑:我意识到我的问题措辞有点差。我不知道如何从CSV获取列号。这是怎么做到的?
此外,一旦我获得了列号,如何告诉CSV运行后续行并仅从该列中获取数据?
答案 0 :(得分: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
答案 1 :(得分:0)
我没有时间写一个完整的例子,但我写了一个可以帮助你做这个的模块。 Tie::Array::CSV使用一些魔法使你的csv文件就像一个arrayrefs的Perl数组。通过这种方式,您可以使用Perl的知识与文件进行交互。
尽管有警告!我的模块的一个好处是它是可读/写的。由于您只想阅读,请注意不要分配给它!