Ваша обработка одинакова для HTML и текстовых файлов, поэтому упростите свою жизнь и выделите общую часть:
sub scrape {
my($path,$pattern,$sep) = @_;
unless (open FILE, $path) {
warn "$0: skipping $path: $!\n";
return;
}
local $/ = $sep;
my $column_name;
while (<FILE>) {
next unless /$pattern/;
$column_name = $1;
last;
}
close FILE;
($path,$column_name);
}
Затем укажите это для двух типов ввода:
sub scrape_html {
my($directory,$i) = @_;
scrape $directory.$i."rank.html",
qr{<title>CIA - The World Factbook -- Country Comparison :: (.+)</title>}i,
"\n";
}
sub scrape_txt {
my($directory,$i) = @_;
scrape $directory.$i."rank.txt",
qr/Rank\s+Country\s+(.+)\s+Date/i,
"\r";
}
Тогда ваша основная программа проста:
my $directory = shift or die "$0: must supply directory\n";
my $year = shift or die "$0: must supply year\n";
die "$0: $directory is not a directory\n"
unless -d $directory;
# add trailing slash if necessary
$directory =~ s{([^/])$}{$1/};
my $columns_file = "columns$year.txt";
open COLUMNS, ">", $columns_file
or die "$0: open $columns_file: $!";
for (my $i = 2001; $i <= 2212; $i++) {
my $process = $year >= 2009 ? \&scrape_html : \&scrape_txt;
my($path,$column_name) = $process->($directory,$i);
next unless defined $path;
if (defined $column_name) {
print "$0: Adding $column_name to text file\n";
print COLUMNS "$column_name\n";
}
else {
warn "$0: no column name in $path\n";
}
}
close COLUMNS or warn "$0: close $columns_file: $!\n";
Обратите внимание, как осторожно вы должны закрывать глобальные файловые дескрипторы. Пожалуйста, используйте лексические дескрипторы файлов, как в
open my $fh, $path or die "$0: open $path: $!";
Передача $fh
в качестве параметра или добавление его в хэши намного приятнее. Кроме того, лексические файловые дескрипторы закрываются автоматически, когда они выходят из области видимости. Нет никакого шанса нажать на ручку, которую уже использует кто-то другой.