我是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之后打印出那些匹配的名字。我不知道如何提取不匹配的名称。 (比较第1列第2名与第2列第2名数据之后的顺序不是顺序排列。)我需要打印每组的名字和姓氏。
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 :(得分: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
在空格上输入autosplit,剥去多余的空格-n
读取标准输入或文件输入@F
数组autosplit元素存储在基本上这个代码循环文件(或stdin)中的每一行,如果该行上的第一个值不等于前一行的第二个值,则打印一个新的group-header,并且计数器递增一个人。
如果你有警告,你会收到两条有关此代码的警告,但是因为它们在这里是无害的(首次检查$a
时未初始化警告,$i
错字警告)我选择不打开警告。
这个单行的完整代码是:
$/ = "\n";
$\ = "\n";
while (<>) {
chomp;
our(@F) = split(' ', $_, 0);
print 'group' . ++$i . ':' if $a ne $F[0];
print $_;
$a = $F[1];
}
答案 1 :(得分: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;
答案 2 :(得分: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”。
答案 3 :(得分:-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