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

First of all, I am by no means a brilliant programmer. I would call my self a business programmer. I do just enough to get it to work without making it as efficient as possible.

Alas, my incorrect attitude is biting me in the rear end now!! As I learn new languages, it is harder for me to understand what is going on. I have never used Perl before last Monday. In the last week I have read "Learning Perl" by Randal Schwartz. I am a “learn by doer” instead of “learn by reader”. I am now experimenting and want a script to do the following:

1 - Recursively search though the specified directory for all files with the ".txt" file extension.

2 - Store them all in an array or that hash thing (which I don't really get ... yet.)

3 - Search all the txt files for the letter combination "happy".

4 - Store all those files and file directory locations in another array or hash thing.

5 - Write the file directory and file name to a mysql db into table "Storage".

6 - Export an HTML file showing the names and locations of all the files to be viewed on a web page.

Since I am lazy (and sick of trying to figure it out myself (Where the heck does that // or \\ go again?)) will some please write me a dumbed down script to do all that?

Please don’t use any short cut stuff because I am trying to learn this and won't be able to understand it. I would be glad to repost the same script after I :

1 - Have understood it

2 - Figured out all the short cuts that should have been there in the first place to make the code as efficient as possible.

Thank you oh wise monks!!!

Replies are listed 'Best First'.
Re: Search and store solution?
by Limbic~Region (Chancellor) on Jul 11, 2008 at 01:52 UTC
    nukeboy,
    This site is about teaching and helping. There are many ways to teach and help, but doing the work for someone is seldom something we do. So before you get excited about the code that I have written for you, consider that it won't work. You will have to work at it in order to make it fit your exact situation.

    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%. This is a moderately complex problem and you have very little experience under your belt. It is unrealistic to expect to start running 10K (about 6 miles) races after a week of training - this is no different.

    Good luck and welcome to the monastery.

    Cheers - L~R

      Well,

      All of the criticism is well deserved. 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 and print +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 my self imposed assignement in chunks. Can someone help me figure out why it is not working? Thanks.
        nukeboy,
        However, I am struggling with find::file so I went back to “Learning Perl” and came up with this:

        Note that my code uses File::Find::Rule which has a very user friendly interface (as opposed to File::Find). I am not sure what was difficult to understand from my example but it does exactly what you asked for.

        I will comment on a few snippets of your code.

        opendir DH, $dir_to_process # Use a lexical ($dir) instead of a bareword global (DH) if possible
        if ($file =~ /\.txt$/) # This would break for a directory called dir.txt - see perldoc -f -X
        %stuff_to_store = ($dir_to_process, $file); # This overwrites the hash entirely every time
        while (%stuff_to_store) { # this will be an infinite loop if the hash contains any items

        Please note: Your code will only search the current directory - it will not descend into sub directories. Out of curiosity, how much time did you spend with the code I wrote before you gave up on it? It really does 97% of what you asked.

        Cheers - L~R

        All of the criticism is well deserved. 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.

        I myself am just learning Perl, and have just recently finished (my first reading of) the Llama. I've started now on the Alpaca (Intermediate Perl) and find the material interesting.

        My best suggestion for you if you are having difficulty learning Perl is to work through the exercises at the end of each chapter in the Llama. The project that prompted me to learn Perl covers some more advanced ideas, so I had to go out and look at complex data structures while still reading the Llama. But the further I got through the book, the more I found that would help with my project, and that I would never have thought of. This site can be a boon to the Perl initiate, but you have to be willing to do the work.

        So yes, you must overcome your laziness. Programmers are a lazy bunch, but (usually) only in the sense that they don't feel the need to re-invent the wheel over and over. Code reuse is one result of this laziness.

        Those are just some of my thoughts.

        %stuff_to_store= (...,...) isn't the way to add something to your hash, it just initializes a hash. Your code will make sure there is always only one hash element in the hash as previous elements are overwritten. Use $stuff_to_store{$dir_to_process}= $file instead.

        Note that you are only storing one file per $dir_to_process here. If you want to have a list of files for every directory, you have to upgrade your code to use a hash of arrays for example

        while (%stuff_to_store) won't loop through your hash, it will loop as long as anything is stored in the hash and since you don't change the hash in the loop that means forever. Try out print scalar %stuff_to_store; to see what I mean. Use

        foreach (keys %stuff_to_store) { print $_,' ',$stuff_to_store{$_},"/n"; }
        to loop through and print out the hash.

        "its not working" is the worst problem description you can make. Try to be more specific by telling what your script prints out and what it should print out.

Re: Search and store solution?
by pc88mxer (Vicar) on Jul 10, 2008 at 21:39 UTC
Re: Search and store solution?
by samtregar (Abbot) on Jul 10, 2008 at 21:47 UTC
    You say you learn best by doing, not by reading. How are you going to learn if you don't do it yourself?

    I think you need to at least take a stab at it first. If you get stuck, post what you have and we'll help you get unstuck.

    -sam

Re: Search and store solution?
by apl (Monsignor) on Jul 10, 2008 at 21:55 UTC
    Ask your teacher to explain hashes again; he'll be glad to spend the time on it. (There are some good tutorials on the subject on this site, but I'm too lazy to provide a link for you.)

    Learning Perl has a great write-up on regular expressions (and on hashes too, come to think of it). Why don't you write as much as you can of the first four tasks, and show it to us? We'll be happy to give you hints after that.

Re: Search and store solution?
by Zen (Deacon) on Jul 10, 2008 at 21:41 UTC
    The super search button is up at the top. If you aren't willing to put forth effort into these things, you can't expect a monk to.
Re: Search and store solution?
by YYCseismic (Beadle) on Jul 14, 2008 at 18:48 UTC

    Reading the comments and suggestions of others, and your response to them, it looks to me as though you've bitten off slightly more than you can chew for a first project. I suggest that, since you've broken down your project into six major goals, you should consider each of those goals as a project in itself. Work on a single item from your list of goals, and when you are happy that it does what you need/want, move on to the next item. When that one's done, maybe play with integrating the two so they work together. The key is to start off simple. The program can build in complexity as you become more comfortable and competent (in Perl), having solved each problem.

    It took me a long time to learn this lesson! And I (stubbornly) had to learn it for each discipline I tackled, be it mathematics, physics, or computer programming.