Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Use of uninitialized value in pattern match (m//)

by chris01010 (Novice)
on Mar 17, 2015 at 22:26 UTC ( [id://1120387]=perlquestion: print w/replies, xml ) Need Help??

chris01010 has asked for the wisdom of the Perl Monks concerning the following question:

I have written a PERL script to read files from directory that the filename contains OT. It then takes each line of each file and prints the first 5 characters before the first occurence of a /.

Currently I am getting the error:

Use of uninitialized value in string at rowGrab.pl line 43.

Use of uninitialized value in pattern match (m//) at rowGrab.pl line 41.

#!/usr/bin/perl use strict; my $log_dir = '/home/user1'; my $trans_dir = '/data/directoy1'; my $file; my $participant; my @files; my $line; if (!open(LOG, " >>$log_dir/trans.log")) { syslog("Warning:","Cannot open log file called: $log_dir/trans.log" +); die "Cannot open the file $log_dir/trans.log, $!"; } undef (@files); opendir(DIR,$trans_dir); my @files = grep { /(OT)/ # Filename contains OT && -f "$trans_dir/$_" # and is a file } readdir(DIR); foreach $file (@files) { print STDERR "File: $file\n"; open(FILE,"<$trans_dir/$file") or die "Cannot open $file"; print "$file\n"; for $line (<FILE>) { ($participant) =~/(.....)\//; print "$participant"; close (FILE); } } closedir(DIR);
Can anyone provide some guidance?

Also prior to putting in string matching, I just printed the filename. This however got the error "Out of memory".

The directory contains 5487 files and each file averages 119 MB.

I understand this is a genuine memory issue, I was just wondering if anyone knew a way round it?

Thanks Chris

Replies are listed 'Best First'.
Re: Use of uninitialized value in pattern match (m//)
by linuxer (Curate) on Mar 17, 2015 at 22:41 UTC

    Your warnings are from lines 41 and 43, your code only has 31 lines... what happened with the rest?

    What is that syslog function your are calling in line 11?

    I think, the following addresses your main cause for the warnings:

    In line 25 you are working on the wrong variable. You should use $line for your regex match; not $_. Your line 25 reads as (ignoring the error at the end): ($participant) = $_ =~ m{(.....)/};

    I would use lexical filehandles and would use more localized variables.

    edit2: I have to correct me completely on that regex line; sorry:

    Your line 25 does a regex match on $participant, which is not defined yet. So there is a regex match against an undefined variable. Line 26 wants to print that undefined variable as well.

    The correction still is to do the regex match on $line and store the result in $participant

    edit: fixed error and rephrased regex, sorry
      Sorry, I removed some debug lines I had in the script which I removed before posting

      The current errors are:

      Use of uninitialized value in string at rowGrab.pl line 26.

      Use of uninitialized value in pattern match (m//) at rowGrab.pl line 25.

      syslog allowa errors to be written to Unix syslog

        Having that cleared, now you can concentrate on your regex issue in line 25 ;-)

        I thought about your code and there are some other topics:

        • use lexical filehandles and the three argument form of open; e.g. see: Perl Maven - Open files in the old way
        • avoid "global" variables; e.g. if you need them only as loop variables; use the smallest scope possible; e.g. no my $i; for $i ( ...); better: for my $i ( ... )
        • Shouldn't you print $participant only if the regex match was successful
        • maybe you can use glob() to find the wanted files?

        Here's an untested rewrite based upon these ideas:

        #!/usr/bin/perl # http://perlmonks.org/?node_id=1120387 use strict; use warnings; my $log_dir = '/home/user1'; my $log_file = "$log_dir/trans.log"; my $trans_dir = '/data/directoy1'; # Log handles if ( not open my $loghandle, ">>", $log_file ) { # lexical hand +le and three argument form of open() # syslog ... # what's this? die "Cannot open file $log_file: $!"; } # maybe instead of opendir ... and readdir ... my @files = grep { -f } glob( "$trans_dir/*OT*" ); foreach my $file (@files) { print STDERR "File: $file\n"; print "$file\n"; open my $fh, "<", $file # same here; l +exical file handle and 3-arg-form of open() or die "Cannot open $file: $!"; while ( my $line = <$fh> ) { if ( (my $participant) = $line =~ m{(.....)/} ) { # expl +icitely use $line for regex print "$participant"; # only + print when match was found } } close $fh; }
        Those are actually warnings - the script keeps running, and probably does what you intended overall (whereas an error would cause the script to halt immediately). I expect that the warnings happen on the last iteration of the "for" loop:
        for $line (<FILE>) {
        The part in parens produces an anonymous array that the "for" will iterate over, and the last element of that array the "undef" element from the last attempt to read from the file handle and encountering 'eof'. If you used a while loop instead, you wouldn't enter the block (lines 25 and 26 would not be reached) on that last attempt to read from the file.
Re: Use of uninitialized value in pattern match (m//)
by jellisii2 (Hermit) on Mar 18, 2015 at 11:51 UTC
    File::Find might make some of your logic unnecessary...
      Thanks jellisii2, I'll have a read.

        File::Find::Rule is a much neater interface to File::Find :)

        use File::Find::Rule qw/ find rule /; my @files = find( file => name => 'OT', maxdepth => 1, in => $trans_dir, );
        now @files contains "$trans_dir/OTfile1" ...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1120387]
Approved by graff
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (2)
As of 2024-04-26 07:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found