4

我想知道您是否可以帮助我解决我无法理解的编码问题。我拥有的制表符分隔数据如下所示:

00001  AU:137  AU:150  AU:180
00001  AU:137  AU:170
00002  AU:180
00003  AU:147  AU:155
00003  AU:155

我想要的输出是:

00001  AU:137  AU:150  AU:180  AU:170
00002  AU:180
00003  AU:147  AU:155

所以第一列(标识符)将合并值,删除重复项,使其成为哈希。我不确定如何处理我当前的数据,因为它不能是具有重复键的哈希。如果标识符相同,我也不确定如何将数据推送到数组中。

我很抱歉没有代码。我确实尝试了一些,实际上,相当多,但即使对于像我这样的新手来说,它们看起来也不合适。

任何帮助,建议将不胜感激,非常感谢您的时间和回答。我非常感激。

4

3 回答 3

3

我希望这能提供一些想法来解决您的问题:

use strict;
use warnings;
use Data::Dumper;

my %hash = ();

while (<DATA>) {
    chomp;
    my (@row) = split(/\s+/);
    my $firstkey = shift @row;

    foreach my $secondkey (@row) {
            $hash{$firstkey}{$secondkey}++;
    }
}

print Dumper \%hash;

__DATA__
00001  AU:137  AU:150  AU:180
00001  AU:137  AU:170
00002  AU:180
00003  AU:147  AU:155
00003  AU:15
于 2012-04-16T08:54:18.593 回答
3

对此的经典解决方案使用哈希;实际上是散列的散列,因为每行都有重复的行号和重复的值。

这个程序产生你需要的输出。它期望数据文件在命令行上传递。

use strict;
use warnings;

my %data;

while (<>) {
  chomp;
  my ($key, @items) = split /\t/;
  $data{$key}{$_}++ for @items;
}

print join("\t", $_, sort keys %{$data{$_}}), "\n" for sort keys %data;

输出

00001 AU:137  AU:150  AU:170  AU:180
00002 AU:180
00003 AU:147  AU:155

或者,如果您更喜欢命令行解决方案

perl -aF/\t/ -lne'$k=shift @F; $d{$k}{$_}++ for @F; END{print join "\t", $_, sort keys %{$d{$_}} for sort keys %d}' myfile

(它可能需要一些调整,因为我目前只能在 Windows 上测试。)

于 2012-04-17T16:40:58.040 回答
0

脚本:

#!/usr/bin/perl

use strict;
use warnings;

my %hash;
sub uniq { return keys %{{map {$_=>1} @_}}; }

open my $fh, '<input.txt' or die $!;
foreach (<$fh>) {
  $hash{$1} .= $2 if /^(\S+)(\s.*?)[\n\r]*$/;
}
close $fh;

foreach (sort keys %hash) {
  my @elements = uniq split /\t/, $hash{$_};
  print "$_\t", join(' ', sort @elements), "\n";
}

输出:

00001    AU:137 AU:150 AU:170 AU:180
00002    AU:180
00003    AU:147 AU:155
于 2012-04-16T13:20:07.140 回答