2013-01-21 30 views
0

我是Perl的新手。感謝任何人都可以給我一些建議和幫助。如何使順序數據成組

我有一個文件:


A1a01 A1a03 
A1a03 A1a0b 
A1a0b A1a2a 
A1a2a A1a02 
A1app A1a06 
Ala06 A1a07 
A1b0v A1b0c 
Alb0c Alb55 
A1b55 A1b04 
..  .. 
..  .. 
. 
. 
. 

我想提取和打印順序數據分成不同的組。從給出的示例中可以看出,這些組來自A1a01到A1a02,A1app到A1a07以及A1b0v到A1b04。每個組都以順序方式。

到目前爲止,我已經嘗試了下面的代碼,但它不能得到我需要的。我只能在比較column1和column2之後打印出那些匹配的名字。我不知道如何提取不匹配的名稱。 (不是按順序比較column1第2個名稱和第2個第2個數據的第1個名稱後的順序)。我需要打印每個組的名和姓。

use strict; 
use warnings; 

my $i; 
my $j; 
my @column1; 
my @column2; 
my @array1; 
my $lastname; 


@column1=`awk '{print \$1}' saved4`; 
@column2=`awk '{print \$2}' saved4`; 

    for ($i=0;$i<=$#column1;$i++){ 
     for ($j=0;$j<=$#column2;$j++){ 
       if ($column1[$i]=~ /$column2[$j]/){ 

        push (@array1,$column2[$j]); 
          } 

     else { 
      $lastname = $column2[$j]; 
      } 

      } 
} 

print "$column1[0] @array1 $lastname\n"; 

預期的結果是這樣的:

group1: 
A1a01 A1a03 
A1a03 A1a0b 
A1a0b A1a2a 
A1a2a A1a02 

group2: 
A1app A1a06 
Ala06 A1a07 

group3: 
A1b0v A1b0c 
Alb0c Alb55 
A1b55 A1b04 
+0

你有意在樣品輸入/輸出混合'1'(頭號)和'l'(小寫L)或是一個錯字? – TLP

回答

3

這可以用一襯墊來完成:

perl -lane 'print "group".++$i.":" if $a ne $F[0]; print; $a = $F[1];' group.txt 

輸出:

group1: 
A1a01 A1a03 
A1a03 A1a0b 
A1a0b A1a2a 
A1a2a A1a02 
group2: 
A1app A1a06 
A1a06 A1a07 
group3: 
A1b0v A1b0c 
A1b0c A1b55 
A1b55 A1b04 

說明:在輸入/輸出

  • -l手柄換行符上的空白
  • -a自動分割輸入,汽提過​​量的空白
  • -n讀取標準輸入或輸入從文件
  • @F陣列自動分割元素存儲在

基本上這個代碼循環爲文件中的每一行(或stdin),如果該行的第一個值不等於前一行的第二個值,則會打印一個新的組標題,並將該計數器加1。

如果你有警告,你會得到兩個警告,此代碼,但由於它們是無害的,這裏(未初始化預警第一支票$a和錯字預警上$i)我選擇不把警告上。

此一襯墊的全碼是:

$/ = "\n"; 
$\ = "\n"; 
while (<>) { 
    chomp; 
    our(@F) = split(' ', $_, 0); 
    print 'group' . ++$i . ':' if $a ne $F[0]; 
    print $_; 
    $a = $F[1]; 
} 
+0

感謝您的幫助= D – Zoe

+0

@Zoe不客氣。 – TLP

-1
use strict; 
use warnings; 

my $i; 
my $j; 
my @column1; 
my @column2; 
my @array1; 
my $lastname; 

@column1=`awk '{print \$1}' saved4`; 
@column2=`awk '{print \$2}' saved4`; 

chomp @column1; 
chomp @column2; 

my @allGroups; 
my $group = [ "- " . $column1[0] . " " . $column2[0]]; 

for ($i = 0; $i <= $#column2; $i++){ 

    if ($i < $#column1-1) { 

     if ($column2[$i]=~ /$column1[$i+1]/) { 

      push (@$group, "- " . $column1[$i+1] . " " . $column2[$i+1]); 

     } else { 
      push (@allGroups, $group); 
      $group = [ " - " . $column1[$i+1] . " " . $column2[$i+1]]; 
     } 
    } 
} 
foreach my $arr (@allGroups) { 
    print "\n\nNEW GROUP\n"; 
    print @$arr; 
} 

OUTPUT:

NEW GROUP 
A1a01 A1a03 A1a03 A1a0b A1a0b A1a2a A1a2a A1a02 

NEW GROUP 
A1app A1a06 A1a06 A1a07 

NEW GROUP 
A1b0v A1b0c A1b0c Alb55 
+0

我試過你的代碼。它完全正常工作。非常感謝=) – Zoe

1
my %groups = (A1a01 => 1, A1app => 2, A1b0v => 3); 

open my $FILE, '<', $ARGV[0] or die "Could not read file $ARGV[0]: $!"; 

flock $FILE, 2; 

while (<$FILE>) { 
    chomp; 

    my @cols = split /\s/; 

    print "\nGroup #$groups{ $cols[0] }:\n" if $groups{ $cols[0] }; 

    print join (' ', @cols), "\n"; 
} 

close $FILE; 
+1

拆分一個空格可能不是一個好主意,而是使用默認拆分。此外,這使得這些組被硬編碼,不是一個非常有用的解決方案,因爲它要求您首先瀏覽輸入。 – TLP

+0

謝謝;)@Jeffery – Zoe

0
#!/usr/bin/perl 
use warnings; 
use strict; 

my (@arr1,@arr2); 
open my $fh, '<', 'file' or die $!; 
while(<$fh>){ 
     my ($x,$y)= split; 
     push @arr1, $x; 
     push @arr2, $y; 
} 
close $fh; 

my $cnt=1; 
print "Group $cnt \n"; 
my $i=0; 
while (1) { 
     if ($arr1[$i+1] eq $arr2[$i]){ 
       print "$arr1[$i] $arr2[$i] \n"; 
     }else{ 
       print "$arr1[$i] $arr2[$i] \n"; 
       print "Group ", ++$cnt , "\n"; 
     } 
     $i++; 
     if ([email protected]){ 
       print "$arr1[$i] $arr2[$i] \n"; 
       last; 
     } 
} 

在運行此:

Group 1 
A1a01 A1a03 
A1a03 A1a0b 
A1a0b A1a2a 
A1a2a A1a02 
Group 2 
A1app A1a06 
A1a06 A1a07 
Group 3 
A1b0v A1b0c 
A1b0c A1b55 
A1b55 A1b04 

注意:您的文件不正確,在某些地方,它被賦予'l'而不是'1'。

+0

謝謝@Guru。這只是匹配我所需要的=) – Zoe