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

Well,

All of the criticism is well deserved (my last post wasn’t very good.) I must overcome my laziness and do as much as I can for myself. Thank you monks for the corrections. I truly wish I had a teacher to ask questions from, but I really am trying to learn Perl on my own. This is not a school assignment.

Thank you to L~R as your code sample really helped me to get started. However, I am struggling with find::file so I went back to “Learning Perl” and came up with this:

#!/usr/bin/perl -w use strict; #declare vars my $dir_to_process; #sclar to hold directory location my $file; #sclar to hold file names my %stuff_to_store; #hash of directory locations and file names $dir_to_process = "." ; #defining starting directory location opendir DH,$dir_to_process or die "Cannot open $dir_to_process for pro +cessing: $!"; #opening dir to process foreach $file (readdir DH) { #cycling through the directory if ($file =~ /\.txt$/) { #looking for file ext .txt open(my $fh, $file) or die "Unable to open '$file' for reading +: $!"; #reading .txt files while (<$fh>) { #cycling through to find happy if (/happy/) { #if its happy then store it in hash stuff_t +o_store with file location %stuff_to_store = ($dir_to_process, $file); while (%stuff_to_store) { #see if it worked by printin +g out each element of hash stuff_to_store print; #its not working and I don't know why } } } close ($fh); } } closedir DH;
I am trying myself imposed assignement in chunks. Can someone help me figure out why it is not working? Thanks.

Replies are listed 'Best First'.
Re: Beginner question
by NetWallah (Canon) on Jul 11, 2008 at 15:58 UTC
    You have an infinite loop:
    while (%stuff_to_store) { #see if it worked by printing out each eleme +nt of hash stuff_to_store print; #its not working and I don't know why }
    You probably want to iterate over the hash thus:
    while (my ($k,$v)= each %stuff_to_store) { #see if it worked by printi +ng out each element of hash stuff_to_store print $_, $v; #its not working and I don't know wh +y }
    But you probably have only one value in the hash. Why the hash ?

    I'm guessing you want a multi-level hash of hash of Array, but perhaps that may be too complicated. If you understand this code, feel free to use it, or ask!:

    push @{ $stuff_to_store{$dir_to_process}{$file} }, $_; # Debug print it.. for ( @{ $stuff_to_store{$dir_to_process}{$file} } ){ print; }

         Have you been high today? I see the nuns are gay! My brother yelled to me...I love you inside Ed - Benny Lava, by Buffalax

Re: Beginner question
by apl (Monsignor) on Jul 11, 2008 at 16:30 UTC
    In Re: Search and store solution?, Limbic~Region said to you:
    The reason I have given you a 97% solution is to illustrate a point. It took me less than 20 minutes to code but it will probably take you more than 2 hours to fine tune the remaining 3%.

    So.... what exactly did you try to do before coming back to the Monastery to ask for help in completing his solution?

Re: Beginner question
by thezip (Vicar) on Jul 11, 2008 at 16:00 UTC

    nukeboy, I've made a few modifications to your code. If you have any questions about why I did something, just ask away!

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $dir_to_process = '.'; my %stuff_to_store; # Get all of the txt files and put them into the @files array opendir(DH, $dir_to_process) or die "Cannot open $dir_to_process: $!"; my @files = grep { /\.txt$/i } readdir(DH); closedir(DH); my $fullname = "$dir_to_process/$file"; # Process each file for my $file (@files) { open(my $fh, "<", $fullname) or die(qq(Unable to open '$fullname' fo +r reading: $!); # I like to explicitly set a $line variable, rather than implicitly +using $_ while (my $line = <$fh>) { #cycling through to find happy if ($line =~ /happy/) { # Here, I'm using %stuff_to_store as a hash of array references # The hash key is the concatenation of the path and the file nam +e # The value for each key is an array reference that contains lin +es # like: # "Line 123: <this is the text of the found line>" push(@{$stuff_to_store{$fullname}, "Line $.: $line"); } } close ($fh); } print Dumper(\%stuff_to_store);

    BTW, this code is untested, so please forgive any errors.

    Update: As pc88mxer dutifully pointed out to me, I neglected to qualify the full path to the file when I was opening it. This has been corrected.


    Your wish is my commandline.