Quick Question

T

thorassic5

Im trying to read a series of files and extract a small, unique piece
of data from each of them, and print it in a log file. grep didnt
seem to be working as i expected, until i realized that the files
werent being opened, and my regex was banging against the <i>names</i>
of the files. heres what i have,
#!/usr/bin/perl
opendir(DIR, ".");
my @files = glob "*.txt";
closedir(DIR);
open(OUT, ">log.log");
foreach $file (@files){
my @user = grep{!/inventory\d{6}/} $file;
print OUT "$_ \n";
}
close OUT;

Where have i led myself astray?

Thanks!
 
U

usenet

#!/usr/bin/perl

Your next line should be:
use strict;
opendir(DIR, ".");
my @files = glob "*.txt";
closedir(DIR);

You don't need opendir to do a glob(). If you are doing a readdir()
then you need opendir().

Also, it's almost always a bad idea to "load up" an array with the
results of an IO operation. Just iterate over the results directly.
open(OUT, ">log.log");

Better to use lexical filehandles and the three-argument form of
open()
foreach $file (@files){
my @user = grep{!/inventory\d{6}/} $file;
print OUT "$_ \n";}

Where have i led myself astray?

I believe you've already deduced that you're matching against the file
name instead of the file contents. You need to look inside the file:

#!/usr/bin/perl
use strict;
use warnings;

open (my $logfile, ">", '/tmp/log.log');

foreach my $file(glob '/tmp/*.txt') {
open (my $in, "<", $file);
while (<$in>) {
print $logfile $_ unless /inventory\d{6}/i;
}
close $in;
}
close $logfile;

__END__
 
M

Mirco Wahab

#!/usr/bin/perl
opendir(DIR, ".");
my @files = glob "*.txt";
closedir(DIR);
open(OUT, ">log.log");
foreach $file (@files){
my @user = grep{!/inventory\d{6}/} $file;
print OUT "$_ \n";
}
close OUT;

Where have i led myself astray?

There are some problems, as David
already pointed out, I won't repeat
his remarks.

I'd like to add the idea to re-structure
the program in order to read the directories
sequentially per Perl-Idiom (opendir/readdir)
and check for "real" files before accessing them:

use strict;
use warnings;

my $dir = shift || '.';
my $not_if = qr/inventory\d{6}/;

open my $outh, '>', 'log.log' or die "can't write $!";

opendir( my $dirhandle, $dir ) or die "can't open $!";
while( my $fname = readdir $dirhandle ) {
my $fpath = $dir.'/'.$fname;
next if not -f $fpath;

open my $fh, '<', $fpath or die "can't read $!";
print $outh "$fname\n" if grep !/$not_if/, <$fh>;
close $fh;
}
closedir $dirhandle;
close $outh;




Regards

M.
 
T

thorassic5

Your next line should be:
use strict;


You don't need opendir to do a glob(). If you are doing a readdir()
then you need opendir().

Also, it's almost always a bad idea to "load up" an array with the
results of an IO operation. Just iterate over the results directly.


Better to use lexical filehandles and the three-argument form of
open()



I believe you've already deduced that you're matching against the file
name instead of the file contents. You need to look inside the file:

#!/usr/bin/perl
use strict;
use warnings;

open (my $logfile, ">", '/tmp/log.log');

foreach my $file(glob '/tmp/*.txt') {
open (my $in, "<", $file);
while (<$in>) {
print $logfile $_ unless /inventory\d{6}/i;
}
close $in;
}
close $logfile;

__END__

Brilliant, this is much closer to what i was hoping for. Switch
[unless] for [if] and its perfect! Thank you!
 
M

Mirco Wahab

my @files = glob "*.txt";
closedir(DIR);
open(OUT, ">log.log");
foreach $file (@files){
my @user = grep{!/inventory\d{6}/} $file;
print OUT "$_ \n";
}
close OUT;
Where have i led myself astray?

There are some problems, as David
already pointed out, I won't repeat
his remarks.

I'd like to add the idea to re-structure
the program in order to read the directories
sequentially per Perl-Idiom (opendir/readdir)
and check for "real" files before accessing them:


use strict;
use warnings;

my $dir = shift || '.';
my $pattern = '.txt';
my $not_if = qr/inventory\d{6}/;

open my $outh, '>', 'log.log' or die "can't write $!";

opendir( my $dirhandle, $dir ) or die "can't open $!";
while( my $fname = readdir $dirhandle ) {
my $fpath = $dir.'/'.$fname;
next if ! -f $fpath
or $fname !~ /$pattern$/;

open my $fh, '<', $fpath or die "can't read $!";
print $outh "$fname\n" if grep !/$not_if/, <$fh>;
close $fh;
}
closedir $dirhandle;
close $outh;


Regards

M.
 
J

Jürgen Exner

Im trying to read a series of files and extract a small, unique piece
of data from each of them, and print it in a log file. grep didnt
seem to be working as i expected, until i realized that the files
werent being opened, and my regex was banging against the <i>names</i>
of the files. heres what i have,
#!/usr/bin/perl

Missing
use strict;
use warnings;
opendir(DIR, ".");

Missing
or die ("Can't open '.' because $!\n";
my @files = glob "*.txt";
closedir(DIR);
open(OUT, ">log.log");


Missing
or die ("Can't open 'log.log' because $!\n";
foreach $file (@files){
my @user = grep{!/inventory\d{6}/} $file;

@files contains the file names. Are you sure you want to match/grep them?

jue
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top