Reputation: 3
I'm trying to create a single of list of IP addresses from a several different lists that are located in the same directory. Each list has other text and words in addition to the IP addresses. I have the following code:
#!/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;
However, I'm running to a problem at line 11. where it says:
No such file or directory at ./testperl.pl line 11.
What am I doing wrong here?
Thanks.
Upvotes: 0
Views: 52
Reputation: 35208
From the documentation for readdir
:
If you're planning to filetest the return values out of a
readdir
, you'd better prepend the directory in question. Otherwise, because we didn'tchdir
there, it would have been testing the wrong file.
Therefore, when opening a file, be sure to include the path information.
open (LIST, "$dir/$file") or die $!;
Alternatively, you could chdir
to the directory that you're reading.
I'd also advise some general modernizing of your code.
autodie
to get better, automatic error messages for file operationsopen
These two and a couple minor fixes would result in the following:
#!/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 core comes with File::Spec
for cross-platform file manipulation. It works but it's awkward. As an alternative though, there is Path::Class
which provides a much cleaner interface to the core library in the backend.
It will require an install, but the following is your script done using this cpan module:
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";
}
}
}
Upvotes: 3