我正在编写这个获取两个命令行参数的Perl脚本:一个目录和一年.在这个目录中有大量的文本文件或html文件(取决于年份).让我们说比如2010年,它包含的文件看起来像这样<number>rank.html
,数字从2001到2212不等.我希望它单独打开每个文件并在html文件中取一部分标题并将其打印到文本文件.但是,当我运行我的代码时,它只会将第一个文件标题打印到文本文件中.它似乎只打开第一个文件2001rank.html而没有其他人.我将在下面发布代码并感谢任何有帮助的人.
my $directory = shift or "Must supply directory\n";
my $year = shift or "Must supply year\n";
unless (-d $directory) {
die "Error: Directory must be a directory\n";
}
unless ($directory =~ m/\/$/) {
$directory = "$directory/";
}
open COLUMNS, "> columns$year.txt" or die "Can't open columns file";
my $column_name;
for (my $i = 2001; $i <= 2212; $i++) {
if ($year >= 2009) {
my $html_file = $directory.$i."rank.html";
open FILE, $html_file;
#check if opened correctly, if not, skip it
unless (defined fileno(FILE)) {
print "skipping $html_file\n";
next;
}
$/ = "\n";
my $line = <FILE>;
if (defined $line) {
$column_name = "";
$_ = <FILE> until m{</title>};
$_ =~ m{<title>CIA - The World Factbook -- Country Comparison :: (.+)</title>}i;
$column_name = $1;
}
else {
close FILE;
next;
}
close FILE;
}
else {
my $text_file = $directory.$i."rank.txt";
open FILE, $text_file;
unless (defined fileno(FILE)) {
print "skipping $text_file\n";
next;
}
$/ = "\r";
my $line = <FILE>;
if (defined $line) {
$column_name = "";
$_ = <FILE> until /Rank/i;
$_ =~ /Rank(\s+)Country(\s+)(.+)(\s+)Date/i;
$column_name = $3;
}
else {
close FILE;
next;
}
close FILE;
}
print "Adding $column_name to text file\n";
print COLUMNS "$column_name\n";
}
close COLUMNS;
Run Code Online (Sandbox Code Playgroud)
换句话说$column_name
,即使我知道html文件不同,在循环中每次传递都设置相同的东西.
如果你使用本地词法转换为文件句柄而不是全局变量,你可能能够更快地调试它,以及打开严格检查:
use strict;
use warnings;
while (...)
{
# ...
open my $filehandle, $html_file;
# ...
my $line = <$filehandle>;
}
Run Code Online (Sandbox Code Playgroud)
这样,在每次循环迭代期间,文件句柄将超出范围,因此您可以更清楚地看到正在引用的内容和位置.(提示:您可能错过了文件句柄关闭的情况,因此下次不正确地重复使用.)
有关open
和文件句柄的最佳实践的更多信息,请参阅:
其他一些观点:
$_
,那是在惹麻烦.声明自己的变量来保存数据:( my $line = <$filehandle>
如上例所示)$1
,$2
等等,只有用括号你真正需要的部分:my ($column_name) = ($line =~ m/Rank\s+Country\s+.+(\s+)Date/i);
如果您应用以上几点,我很确定您会发现您的错误.我在进行最后一次编辑时发现了它,但我想如果你自己发现它,你会学到更多.(我不是想要傲慢;相信我!)