Perl:读取列并转换为数组

时间:2018-07-12 06:08:59

标签: perl

我是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;

谢谢

2 个答案:

答案 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]);
}

这将创建/附加找到的每个项目的列表,并导致哈希值,其中键是左侧项目,而值是右侧项目列表。然后,您可以根据需要处理或重新分配值。