我正在尝试从位于同一目录中的几个不同列表中创建一个IP地址列表。除IP地址外,每个列表还有其他文本和单词。我有以下代码:
#!/usr/bin/perl
use strict;
use warnings;
my $dir = "/home/RHart1/blacklists";
opendir(my $dh, $dir) or die "cannot open directory";
my @lists = grep(/(((\w+[-_]\w+){1,5})\.\w+)$/,readdir($dh));
foreach my $file (@lists) {
open (LIST, "$file") or die $!;
while (<LIST>) {
open (OUTPUTLIST, '>>badguys.txt');
if (/^(([0-9]{1,3}\.){3}[0-9]{1,3}($|\/([0-9]{1,2})))$/) {
print OUTPUTLIST "$1\n";
}
close $file;
}
}
close OUTPUTLIST;
closedir $dh;
但是,我在第11行遇到了问题。它说:
No such file or directory at ./testperl.pl line 11.
我在这里做错了什么?
感谢。
答案 0 :(得分:3)
来自readdir
的文档:
如果您计划对
readdir
之外的返回值进行文件测试,则最好先添加相关目录。否则,因为我们没有chdir
,所以它会测试错误的文件。
因此,在打开文件时,请务必包含路径信息。
open (LIST, "$dir/$file") or die $!;
或者,您可以chdir
到您正在阅读的目录。
我还建议您对代码进行一般性的现代化改造。
这两个和一些小修正将产生以下结果:
#!/usr/bin/perl
use strict;
use warnings;
use autodie;
my $dir = "/home/RHart1/blacklists";
open my $outfh, '>>', 'badguys.txt';
opendir my $dh, "$dir";
while ( my $file = readdir $dh ) {
next unless $file =~ /(\w+[-_]\w+){1,5}\.\w+$/;
open my $fh, '<', "$dir/$file";
while (<$fh>) {
if (/^(([0-9]{1,3}\.){3}[0-9]{1,3}($|\/([0-9]{1,2})))$/) {
print $outfh "$1\n";
}
}
}
Perl核心附带File::Spec
用于跨平台文件操作。它有效,但很尴尬。作为替代方案,有Path::Class
可以为后端的核心库提供更清晰的界面。
需要安装,但以下是使用此cpan模块完成的脚本:
use strict;
use warnings;
use autodie;
use Path::Class;
my $dir = dir('', 'home', 'RHart1', 'blacklists');
open my $outfh, '>>', 'badguys.txt';
while (my $file = $dir->next) {
next unless $file->basename =~ /(\w+[-_]\w+){1,5}\.\w+$/;
my $fh = $file->openr();
while (<$fh>) {
if (/^(([0-9]{1,3}\.){3}[0-9]{1,3}($|\/([0-9]{1,2})))$/) {
print $outfh "$1\n";
}
}
}