我是perl的新手,尝试读取带有列的文件并创建一个数组。 我有一个包含以下各列的文件。
file.txt
A 15
A 20
A 33
B 20
B 45
C 32
C 78
我想为A中存在的每个唯一项创建一个数组,并从第二列分配其值。 例如:
@A = (15,20,33)
@B = (20,45)
@C = (32,78)
尝试以下代码,仅用于打印2列
use strict;
use warnings;
my $filename = $ARGV[0];
open(FILE, $filename) or die "Could not open file '$filename' $!";
my %seen;
while (<FILE>)
{
chomp;
my $line = $_;
my @elements = split (" ", $line);
my $row_name = join "\t", @elements[0,1];
print $row_name . "\n" if ! $seen{$row_name}++;
}
close FILE;
谢谢
答案 0 :(得分:3)
首先,一些一般的Perl建议。如今,我们喜欢使用词法变量作为文件句柄,并将三个参数传递给open()
。
open(my $fh, '<', $filename) or die "Could not open file '$filename' $!";
然后...
while (<$fh>) { ... }
但是,假设您的文件名位于$ARGV[0]
中,另一个技巧是使用空文件输入运算符(<>
),该运算符将返回@ARGV
中命名的文件中的数据,而不会您必须打开它们。因此,您可以完全删除open()
行并将while
替换为:
while (<>) { ... }
第二条建议-不要将此数据存储在单独的数组中。将其存储在更复杂的数据结构中要好得多。我建议使用一个哈希,其中的键是字母,值是一个包含所有与该字母匹配的数字的数组。这很容易构建:
use strict;
use warnings;
use feature 'say';
my %data; # I'd give this a better name if I knew what your data was
while (<>) {
chomp;
my ($letter, $number) = split; # splits $_ on whitespace by default
push @{ $data{$letter} }, $number;
}
# Walk the hash to see what we've got
for (sort keys %data) {
say "$_ : @{ $data{$_ } }";
}
答案 1 :(得分:1)
将循环更改为:
while (my $line = <FILE>)
{
chomp($line);
my @elements = split (" ", $line);
push(@{$seen{$elements[0]}}, $elements[1]);
}
这将创建/附加找到的每个项目的列表,并导致哈希值,其中键是左侧项目,而值是右侧项目列表。然后,您可以根据需要处理或重新分配值。