我有2个文件,这种格式具有相同的行
例如
档案1
string1:string2:string3
string4:string6:string6
string7:string8:string9
file2的
string1:string2:string3
string4:string6:string6
string7:string8:string9
我必须对这些文件做一些工作,但我在写作的开始,所以首先我做了这个
foreach my $firstFileString(<FILE1>){
my @firstArray = split(/:/,$firstFileString);
foreach my $secondFileString(<FILE2>){
my @secondArray = split(/:/,$secondFileString);
print "$firstArray[0]\n";
}
}
在继续执行该程序之前 ,我在输出中遇到了此问题,在此行中print "$firstArray[0]\n";
我总是string1
。我期待string1, string4,string7
怎么可能?
提前感谢。
答案 0 :(得分:2)
您的程序会为string1
首时间的每一行打印file2
。
当内循环退出,外循环继续读取file1
的第二行时,文件句柄FILE2
已经在文件末尾,所以没有什么可读的了并且永远不会再输入内循环。
解决此问题的最佳方法是在外部循环中打开file2
,以便在您想要通读它时始终位于文件的开头。最好使用词法文件句柄($file1
而不是FILE1
)并使用while
读取文件,该文件一次读取一行文件,而不是{{1} },它读取整个文件,然后遍历内存中的行。
foreach
<强>输出强>
use strict;
use warnings;
use 5.010;
use autodie;
open my $file1, '<', 'file1.txt';
while (my $line1 = <$file1>) {
chomp $line1;
my @fields1 = split /:/, $line1;
open my $file2, '<', 'file2.txt';
while (my $line2 = <$file2>) {
chomp $line2;
my @fields2 = split /:/, $line2;
print "$fields1[0]\n";
}
}
<强>更新强>
正如您所说,另一种方法是将整个string1
string1
string1
string4
string4
string4
string7
string7
string7
读入数组。这样你就不必多次重新打开和阅读文件了。
由于您将数据存储在内存中,因此您也可以将其分成字段,以便多次保存。这个程序显示了如何。 file2
被读入数组file2
,其中每个元素都是一个字段数组。
现在,内部循环所要做的就是将@file2
设置为数组的每一行。它是一个数组引用,因此字段为$fields2
,$fields2->[0]
等。
$fields2->[1]
答案 1 :(得分:2)
问题是,你第一次通过外循环读到FILE2。第二次通过外部循环,它位于文件的末尾,所以这段代码:
foreach my $secondFileString(<FILE2>){
什么都不做。如果您希望FILE2再次读取,您可以在循环中关闭并打开它,或者寻找
foreach my $firstFileString(<FILE1>){
my @firstArray = split(/:/,$firstFileString);
seek FILE2, 0, SEEK_SET;
foreach my $secondFileString(<FILE2>){
my @secondArray = split(/:/,$secondFileString);
print "$firstArray[0]\n";
}
}
虽然那个输出是
string1
string1
string1
string4
string4
string4
string7
string7
string7
因为你在内循环中打印,所以每件东西都会重复三次。也许你打算在迭代之前在外部循环中打印FILE2
?