Quick Question

Discussion in 'Perl Misc' started by thorassic5@gmail.com, Feb 20, 2007.

  1. Guest

    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!
     
    , Feb 20, 2007
    #1
    1. Advertising

  2. Guest

    On Feb 20, 10:41 am, wrote:
    > #!/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__
     
    , Feb 20, 2007
    #2
    1. Advertising

  3. Mirco Wahab Guest

    wrote:
    > #!/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.
     
    Mirco Wahab, Feb 20, 2007
    #3
  4. Guest

    On Feb 20, 11:07 am, wrote:
    > On Feb 20, 10:41 am, wrote:
    >
    > > #!/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__


    Brilliant, this is much closer to what i was hoping for. Switch
    [unless] for [if] and its perfect! Thank you!
     
    , Feb 20, 2007
    #4
  5. Mirco Wahab Guest

    wrote:
    > 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.
     
    Mirco Wahab, Feb 20, 2007
    #5
  6. wrote:
    > 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
     
    Jürgen Exner, Feb 20, 2007
    #6
  7. Dr.Ruud Guest

    schreef:

    > open (my $logfile, ">", '/tmp/log.log');
    > [...]
    > open (my $in, "<", $file);


    Look ma, no checks.
    :)

    --
    Affijn, Ruud

    "Gewoon is een tijger."
     
    Dr.Ruud, Feb 20, 2007
    #7
  8. <> wrote:

    > Subject: Quick Question



    Please put the subject of your article in the Subject of your article.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Feb 21, 2007
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jack
    Replies:
    1
    Views:
    908
  2. jack

    Quick perl question 2

    jack, Aug 25, 2003, in forum: Perl
    Replies:
    1
    Views:
    909
  3. Jorell

    Quick Question

    Jorell, Aug 8, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    313
    Jorell
    Aug 8, 2003
  4. =?Utf-8?B?UnlhbiBTbWl0aA==?=

    Quick Question - Newby Question

    =?Utf-8?B?UnlhbiBTbWl0aA==?=, Feb 14, 2005, in forum: ASP .Net
    Replies:
    4
    Views:
    670
    Iain Norman
    Feb 16, 2005
  5. JKop
    Replies:
    11
    Views:
    904
Loading...

Share This Page