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

There are 5 rtf files and 3 txt files ... The rtf file name is mentioned in any one txt file . Im trying to print the rtf file name and the corresponding txt file name.. the snippet is

foreach $file (glob('*.rtf')) { open(my $fh, $file) or die("Unable to open '$file': $!"); while (my $line = <$fh>) { if ($line =~ m/(Apple|Orange|Litchi)/i) { $Sheet->Cells($row,$col-1)->{'Value'} = $file; } } foreach my $files (glob('*.txt')) { open(my $fh1, $files) or die("Unable to open '$files': $!"); if ( grep /$file/i, <$fh1> ) { $Sheet->Cells($row,$col+1)->{'Value'} = $files; } else { $Sheet->Cells($row,$col+1)->{'Value'} = "No Text Files"; } $row=$row+1; close $fh1; } close($fh); }
The ouput im expecting is as follows:- RTF File Name TXT File Name 1 No Text Files 2 a 3 No Text Files 4 b 5 c

1,2,3,4,5 are the rtf file names and a,b,c are the text file names...2 is present in a.txt so it is printed along with 2 similarly for 4 and 5...1 and 2 arent traced so No text files is displayed..but the output what im getting is

RTF File Name TXT File Name 1 No Text Files No Text Files No Text Files 2 a No Text Files No Text Files 3 No Text Files No Text Files No Text Files 4 No Text Files b No Text Files 5 No Text Files No Text Files c

i.e every file is opened and No text file is repeated based upon the no of txt file ..how to break the loop..

Replies are listed 'Best First'.
Re: GREP ISSUE
by sauoq (Abbot) on May 11, 2012 at 14:56 UTC

    You are iterating through all of your text files for each rtf file and outputting something for each of them. If I'm reading your question right (and it's not very well asked, imho) it seems like what you want to do is accumulate your results first and then output something. Instead of (pseudocode):

    for my $textfile (@textfiles) { if (grep) { output_this_result; } else { output_that_result; } }
    You want something like (more pseudocode):
    for my $textfile (@textfiles) { if (grep) { push @results, $textfile; } } do_something_with(@results);
    And if @results is empty, then that's when you'll record "No Text Files".

    Note though that it probably doesn't make sense to open and read each text file once for each filename you are looking for. Just read each text file once and check for all of your filenames at the same time.

    Also, you probably want to use quotemeta on your filename before using it as a pattern and maybe add some boundary checking. A filename like foo.rtf would match fooXrtf and bigfoo.rtf or foo.rtf.old. Maybe it doesn't matter for your needs, but you should be aware of it.

    -sauoq
    "My two cents aren't worth a dime.";