Perl对来自两列的数据进行分组

时间:2014-03-21 15:02:42

标签: perl grouping rows

我目前有一个perl脚本,它以这种方式附加到包含内容的文件:

a 1
b 2
c 3
a 2
b 3
c 4
a 3
b 4
c 5

我希望输出如下:

 a 1 2 3
 b 2 3 4
 c 3 4 5

这是我的代码,它从文件中提取2列:

open my $file_in, "<", "input_file.txt" or die($!);
open my $file_out,   '>', 'output_file.txt' or die $!;

$now_string = localtime;
print "$now_string\n";
while( <$file_in> ) {
    next unless $i++;
    my @columns = split /\s+/, $_;
    print $file_out "$now_string\t$columns[0]\t$columns[2]\n";

}
close $file_in;
close $file_out or die $!;

有什么想法吗?我正在使用Solaris 9机器,因此无法运行perl模块或类似的perl -E,perl -lane。提前致谢。

5 个答案:

答案 0 :(得分:1)

perl -le'
  push @{$h{$_->[0]}}, $_->[1] for map [split], <>;
  print join " ", $_, @{$h{$_}} for sort keys %h;
' file

perl script.pl input_file.txt > output_file.txt

$\ = "\n";
push @{$h{$_->[0]}}, $_->[1] for map [split], <>;
print join " ", $_, @{$h{$_}} for sort keys %h;

更长(和近似)版本,

$\ = "\n"; # append newline when invoking print

my %h;
# read lines from STDIN
while (<>) {
  # split line on white spaces
  my @F = split;
  # push value of second column into $h{$F[0]} array
  push @{ $h{$F[0]} }, $F[1];
}

# sort unique values of first column
for my $k (sort keys %h) {

  # print value of first column, 
  # together with values belonging to it
  print join " ", $k, @{ $h{$k} };
}

答案 1 :(得分:0)

很简单,但是到目前为止知道你如何获得数据会有所帮助吗?

你需要一个HashArray。有点像:

$x->{'a'} ||= []; # init array
push $x->{'a'}, 1; # add value

...

foreach my $h (keys %$x){
 print $h;
 foreach my $a (@{$h->{ $h }}){
  print $h->{ $h }; 
 }
 print "\n";
}

我没有运行代码,只是在这里破解了它。

答案 2 :(得分:0)

也许您想partition_by来自List::UtilsBy

use 5.010;
use List::UtilsBy 'partition_by';

my @pairs = (
  [ 'a', 1 ],
  [ 'b', 2 ],
  ...
);

my %groups = partition_by { $_->[0] } @pairs;

foreach my $group ( sort keys %groups ) {
  say "Group $group: " . join " ", @{$groups{$group}};
}

答案 3 :(得分:0)

perl -lane "
  push @{$v{shift @F}}, @F; 
  END { print qq{$_ @{$v{$_}}} for sort keys %v }
" file1.txt

输出:

a 1 2 3
b 2 3 4
c 3 4 5

答案 4 :(得分:0)

至少你应该把你尝试过的东西放到目前为止,而不仅仅是问题。您可以使用哈希轻松完成。

use Data::Dumper;
use autodie;

# Parse text file
open(FH,$ARGV[0]);
my @array=<FH>;
my %hash;

foreach(@array)
{
    $_=~m/(\w+)\s(\w+)/;
    push(@{$hash{$1}},$2);
}

print Dumper \%hash;