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 2nd name 和column2 1st name of 2 rows data 之后的顺序不是顺序的。)我需要打印每个组的名字和姓氏。

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  
4

4 回答 4

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数组自动拆分元素存储在

基本上这段代码循环文件(或标准输入)中的每一行,如果该行的第一个值不等于前一行的第二个值,则打印一个新的组头,并且计数器加一。

如果您打开了警告,您将收到与此代码有关的两个警告,但由于它们在这里是无害的(首次检查的未初始化警告$a和错字警告打开$i)我选择不打开警告。

这个单行代码的完整代码是:

$/ = "\n";
$\ = "\n";
while (<>) {
    chomp;
    our(@F) = split(' ', $_, 0);
    print 'group' . ++$i . ':' if $a ne $F[0];
    print $_;
    $a = $F[1];
}
于 2013-01-21T17:14:59.080 回答
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;
于 2013-01-21T15:47:46.803 回答
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 ($i+1==@arr1){
                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”。

于 2013-01-21T15:48:15.103 回答
-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;
}

输出:

NEW GROUP
A1a01    A1a03 A1a03    A1a0b A1a0b    A1a2a A1a2a    A1a02

NEW GROUP
A1app    A1a06 A1a06    A1a07

NEW GROUP
A1b0v    A1b0c A1b0c    Alb55
于 2013-01-21T15:43:31.500 回答