2014-05-11 48 views
0

我有一個製表符分隔文件:數組排序來獲得獨特的記錄

AA  11 
AA  22 
AA  11 
AA  22 
BBB  44 
BBB  77 
BBB  44 
BBB  77 

我要打印的文件不同的線路:

AA  11 
AA  22 
BBB  44 
BBB  77 

我寫了這個Perl腳本做即:

#!/usr/bin/perl 
$file1=$ARGV[0]; 
%record; 
open(FP1,"$file1"); 
while($s1=<FP1>) 
{ 
    chomp($s1); 
    @array= split(/\t/,$s1); 
    $name1=$array[0]; 
    $name2=$array[1]; 
    push @{$record{$name1}{trs}}, $name2; 
    $ref=\%record; 
} 
for $name1 (sort { $a <=> $b } keys %record) 
{ 
    my $name2 = $$ref{$name1}{trs}; 
    print "$name1\t$name2\n"; 
} 

但它不起作用。有人可以幫忙嗎?

+1

'perl -ne'print除非$ seen {$ _} ++'file'是單行等價物。 – TLP

回答

3

你不必閱讀整個文件到內存第一,如果你不想換線訂購,

use strict; 
use warnings; 
use autodie; 

my $file1 = $ARGV[0]; 
my %seen; 
open(my $FP1, "<", $file1); 

while (my $s1 = <$FP1>) { 
    next if $seen{$s1}++; 
    print $s1; 
} 
1

的主要問題是您存儲AA記錄在一個陣列稱爲@{$record{'AA'}{trs}} (即@{$record{'AA'}->{'trs'}}),但是當您打印這些記錄時,您不會遍歷該數組,您只需將其作爲標量讀取即可。

您的文件是製表符分隔的事實似乎並不相關,因爲如果兩條記錄不同,您顯然認爲兩行不同。因此,您不必擔心將行轉換爲「記錄」進行處理的複雜性。

(即使從不談,你有例子很多不必要的代碼—,沒有任何理由可言創建$ref。)

實際上,你可以只用Perl免除,並使用標準sort實用程序:

sort -u <INPUT_FILE >OUTPUT_FILE 
+0

感謝您糾正我。 – firoz

1

如果相匹配的行正是那麼所有你需要的是從List::MoreUtils

uniq功能
use strict; 
use warnings; 

use List::MoreUtils 'uniq'; 

my @data = <DATA>; 
chomp @data; 
print "$_\n" for uniq @data; 


__DATA__ 
AA 11 
AA 22 
AA 11 
AA 22 
BBB 44 
BBB 77 
BBB 44 
BBB 77 

輸出

AA 11 
AA 22 
BBB 44 
BBB 77 

如果您不能安裝List::MoreUtils和有沒有uniq做,那麼你會寫這樣的事情

use strict; 
use warnings; 

use List::MoreUtils 'uniq'; 

my @data = <DATA>; 
chomp @data; 

my (@unique, %unique); 
for (@data) { 
    push @unique, $_ unless $unique{$_}++; 
} 

print "$_\n" for @unique; 

輸出是完全相同的前面的例子。