http://www.perlmonks.org?node_id=1015083

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

I need to copy each row of a document that contains the words "make", "model", "year". I will need each row to be put into a new file.

I need to repeat for 300 files. They are located in the same folder and all copied data will be written to the same file. The documents are long but the words are guaranteed to be in the top 30 rows.

I'm still new to Perl and all the help is much appreciated. I'd rather not have to open every file and copy data manually.

Thanks!

Replies are listed 'Best First'.
Re: Copy rows of file to new document
by vinoth.ree (Monsignor) on Jan 24, 2013 at 07:27 UTC

    Just giving you an idea

    Assuming you files are text files

    1.Opening the directory which contains your 300 files using the opendir() function
    #!/usr/bin/perl use strict; use warnings; my $dir_path="Your Directory Path"; opendir (DIR, $tmp_dir) or die $!;

    2.Open the destination file with the appending modeopen() function

    open (MYFILE, '>>data.txt');

    3.Reading each files using the readdir function. readdir returns the name of each file or directory in the opened directory in turn when used in scalar context, or a list of the names of all files and directories in that directory when used in list context.

    while (my $file_name = readdir(DIR)) {print "$file_name\n";}

    4.Within this loop open each file in read mode and do another loop to each all the content and check for whatever the word match you need with regular expression. If matches write that content into the "data.txt" file as  print MYFILE $file_content; Once each file completes close each file respectively  close (MYFILE);

    use the function closedir function to close the opened directory

      I tried but I can't seem to get it to work. I'm really new to this all. If I can't figure it out then I'll have to start doing them manually.

      My data is located in the directory 'c:\incoming\temp'. I don't know if I should make a file or will the script make it for me? Any help will be appreciated, even if you have to write it out exactly for me. I know you guys have tried to make it as clear as possible but I'm really having such a difficult time. I have so much work today and the boss won't be paying me if I have to catch up on the weekend. I'm as desperate as one can be to get this thing to work. Once again, all the help is appreciated.

      #!/usr/bin/perl use strict; use warnings; my $dir_path="\Incoming\Temp"; opendir (Incoming\Temp, $tmp_dir) or die $!; open (MYFILE, '>>vehicles.txt'); while (my $file_name = readdir(Incoming\Temp)) {print "$file_name\n";} print MYFILE $file_content; close (MYFILE); CLOSEDIR;
        • my $dir_path="\Incoming\Temp";
          This is not doing what you think. The backslash has a special meaning in double quotes. Fortunately, you can use a normal slash /.
        • opendir (Incoming\Temp, $tmp_dir) or die $!;
          Where is $tmp_dir coming from? Do you mean $dir_path? Moreover, you cannot use a non-alphanumeric character in a dirhandle name. Remove the backslash. Even better - use a lexical dirhandle:
          opendir my $DIR, $dir_path or die $!;
        • open (MYFILE, '>>vehicles.txt');
          Not really an error, but can be improved: use a lexical filehandle, 3-argument version of open, and test for failure:
          open my $OUT, '>>', 'vehicles.txt' or die $!;
        • Also note that $file_content is empty and undeclared. You probably want to use it inside the while loop to populate the output file:
          while (my $filename = readdir $DIR) { open my $FILE, '<', "$dir_path/$filename" or die $!; while (my $content = <$FILE>) { print $OUT $content; } }
          BTW, have you noticed the directory path must be prefixed to the filename?
        • CLOSEDIR;
          Perl is case sensitive. The function is in lowercase: closedir. Also, give it an argument.
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Copy rows of file to new document
by 2teez (Vicar) on Jan 24, 2013 at 07:12 UTC

    ..I'm still new to Perl and all the help is much appreciated..

    To get all the help you will want, Please check How do I post a question effectively?

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
Re: Copy rows of file to new document
by tmharish (Friar) on Jan 24, 2013 at 08:08 UTC
    dir/with/files$ ls -A | xargs head -qn 30 | perl -Mstrict -wne 'if( $ +_ =~ /(make)|(model)|(year)/ ) { print "$_"; }' > youtoutfile.txt
Re: Copy rows of file to new document
by nagalenoj (Friar) on Jan 24, 2013 at 09:19 UTC
    If you are using linux machine. You've been already blessed with grep command.

    Something like,
    grep -rE "(make|model|year)" dir/
    Filter top 30 lines as given in tmharish's reply with xargs and head.

      My folder of files is 'c:\vehicles'. The file I want to write to is 'vehicles.txt' and located in 'c:\'. I tried the following code work for what you suggested. I know I've written it wrong. What should I do to correct it?

      C:\vehicles $ ls -A | xargs head -qn 30 | perl -Mstrict -wne 'if( $ + +_ =~ /(make)|(model)|(year)/ ) { print "$_"; }' > vehicles.txt grep -rE "(make|model|year)" c:

        What is $ +_? Do you mean $_?

        If so, then you can omit it and use just: 'if( /(make)|(model)|(year)/ ) { print "$_"; }'.

        Whether that fixes all your problems I doubt; but its one less to deal with.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        Only works on Linux

Re: Copy rows of file to new document
by Rahul6990 (Beadle) on Jan 24, 2013 at 06:49 UTC

    Hi,

    Please provide your effort.What have you written so far and where are you stuck.