此处提供三种方法实现“将两个文件中相同行号的行连接成一行”。
前两种方法也可以细节化的呈现Perl中foreach和while的区别。
第三种方法基于数组的处理,只用一层循环即可实现。
1、method1是用嵌套的两个foreach循环来实现该功能。
#!/usr/bin/perl
open LISTA, "listA" or die $!;
open LISTB, "listB" or die $!;
open CONNECT, ">list_meth1" or die $!;
@list_A = <LISTA>;
@list_B = <LISTB>;
$count1 = 0;
$count2 = 0;
foreach my $list_A(@list_A){
chomp $list_A;
$count1++;
my $lineA = $list_A;
foreach my $list_B(@list_B){
$count2++;
chomp $list_B;
my $lineB = $list_B;
my $lines = "$lineA" . " " . "$lineB";
if($count2 == $count1){
print CONNECT "$lines\n";
print "$lines $count1\n";
}
}
$count2 = 0;
}
close LISTA;
close LISTB;
close CONNECT;
注意:$count2是全局变量,没有采用my $count2这种局部变量。这是为了每次从外层循环进入内层循环时,count2都是从0开始,而不是继续上一次内层循环的连加。如果listA和listB都有100行,那么处理次数有100X100=10000次
2、method2是用foreach内嵌套while循环来实现该功能。
#!/usr/bin/perl
open LISTA, "listA" or die $!;
open LISTB, "listB" or die $!;
open CONNECT, ">list_meth2" or die $!;
@list_A = <LISTA>;
$count1 = 0;
$count2 = 0;
foreach my $list_A(@list_A){
chomp $list_A;
$count1++;
my $lineA = $list_A;
while ($list_B = <LISTB>){
$count2++;
chomp $list_B;
my $lineB = $list_B;
my $lines = "$lineA" . " " . "$lineB";
print CONNECT "$lines\n";
print "$lines $count1\n";
last;
}
}
close LISTA;
close LISTB;
close CONNECT;
注意:为了展示出method1和method2的区别,method1被删除的部分留下了空行。除了内层循环从foreach语句变成while语句之外,内层的while循环中加了last语句,用于立刻结束内层循环,可以跳到外层循环。如果listA和listB都有100行,那么处理次数有100X1=100次
Example:
listA 文本内容如下:
ADD_SVT08
DFF_LVT08
LATCH_ULT08
listB 文本内容如下:
SVT08_ADD
LVT08_DFF
ULT08_LATCH
两个文本的相同行号内容相连接之后产生的文件内容如下:
ADD_SVT08 SVT08_ADD
DFF_LVT08 LVT08_DFF
LATCH_ULT08 ULT08_LATCH
foreach 和 while 两者的不同之处在于它们背后的运作方式:
在while循环里,Perl会读入一行输入,把它存入某个变量并且执行循环主体。然后,它再回头去找其他的输入行。 while循环是一行一行处理。
在foreach循环中,整行输入操作符会在列表上下文中执行(因为foreach需要逐行处理列表的内容)。在foreach循环开始执行之前,它必须先将输入全部读进来。
当输入大容量的文件时,使用foreach会占用大量的内存。两者的差异会十分明显。因此,最好的做法,通常是尽量使用while循环的简写,让它每次处理一行。
3、method3是基于数组再采用foreach循环的方法来实现该功能。
该方法只用一层foreach循环。
#!/usr/bin/perl
open LISTA, "listA" or die $!;
open LISTB, "listB" or die $!;
open CONNECT, ">list_meth3" or die $!;
@list_A = <LISTA>;
@list_B = <LISTB>;
@list_all = (@list_A, @list_B);
$count = 0;
foreach my $list_all(@list_all){
chomp $list_all;
$count++;
$cellnum = ($#list_all+1)/2;
if($count <= $cellnum){
$lines[$count-1] = "$list_all[$count-1]" . " " . "$list_all[$count-1+$cellnum]";
print CONNECT $lines[$count-1]";
chomp $lines[$count-1];
print "$lines[$count-1] $count\n";
}
}
}
close LISTA;
close LISTB;
close CONNECT;