Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Using grep to pick out Specific lines in a text file

by itguy87 (Novice)
on Apr 11, 2013 at 19:15 UTC ( [id://1028212]=perlquestion: print w/replies, xml ) Need Help??

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

Hello there i am trying to use grep to find lines in a file and pull the full line. I have it working when looking for a small text but when i look for one that has a TAB between the lines it can not find it...

So need both the unknown type(0x134e) and 30.6511 lines to be searched but its not working

foreach $_ (@array) { @array2 = grep {$_ =~ "unknown type(0x134e) 30.6511 (V6.5.1 FP1)"} (@array); print FILE "@array2"; close(FILE);

Replies are listed 'Best First'.
Re: Using grep to pick out Specific lines in a text file
by hdb (Monsignor) on Apr 11, 2013 at 19:26 UTC

    Reformatting your code shows a number of things:

    foreach $_ (@array) { @array2 = grep {$_ =~ "unknown type(0x134e) 30.6511 (V6.5.1 FP1)"} ( +@array); print FILE "@array2"; close(FILE);

    • The foreach loop is not closed.
    • The use of $_ in this loop might cause disruption with the $_ implied by grep. Better use $line or such.
    • In the foreach loop over each element of @array you apply grep to @array. This is a duplicated loop.
    • There is a file handle FILE coming out of the blue.
    Could you add a couple of lines of your files, matching and non-matching, that the question becomes easier to understand?

      here is the full code

      use strict; use warnings; my $RootDir = "C:\\Perl"; my $AppDir = "$RootDir\\ibmscripts\\stlogsearch"; my $EtcDir = "$AppDir\\etc\\"; my $sendmail = "C:\\usr\\lib\\sendmail"; my $emailconf = $EtcDir . "email_justme.cfg"; my $outfile = "output.txt"; #my $finallist = "output.txt"; open(FILE, "<data/04102013_loginlogs.txt"); my @array = <FILE>; close(FILE); open(FILE, ">>output.txt"); my @array2 = <FILE>; print "Extracting\n"; foreach $_ (@array) { @array2 = grep {$_ =~ "(0x1346)"} (@array); print FILE "@array2"; close(FILE); system("copy $emailconf $outfile"); open(FILE,">>$outfile"); print FILE "@array2"; close(FILE); system("$sendmail -t < output.txt"); exit;}

        Have you actually walked through the logic of when files are being opened and closed?

        It doesn't make any sense to me to open a file for append mode on line 16, try to read from that file on line 17, print to it on line 21, close it on line 22, open it again on line 25, print to it on line 27, close it on line 29, and then try to print to a closed filehandle on the next iteration of the loop on line 21 again. I think once you sort that out you'll be better off.

        For the sort of thing you're trying to do, slurping into an array and running grep on it repeatedly in a loop isn't really "how it's done". Your situation may be a little more complicated than this, but here's the general algorithm:

        • Open your input and output files.
        • Using a while loop, read from input file: while( <FILE> ) {....
        • Inside the while loop filter for lines of interest (one at a time).
        • Inside the while loop, process the lines of interest (one at a time); in your case, write them to an output/append file.
        • Close the while loop's scope.
        • Close your output and input files.

        Also, place use autodie; toward the top of your script, near the use strict;, so that you can get some basic sanity checking on your file operations.


        Dave

        ...and here now with reading from and writing to file. I leave the system commands out as I do not know what they are intended for.

        use strict; my @patterns = ( 'unknown type\(0x134e\)', '30.6511', '\(V6.5.1 FP1\)' + ); # now read from file instead open FILE, "<", "data/04102013_loginlogs.txt" or die "Cannot open inpu +t file.\n"; my @array = <FILE>; close(FILE); # open output file for writing open OUT, ">>", "output.txt" or die "Cannot open output file.\n"; foreach my $line (@array) { print OUT $line if scalar grep { $line =~ /$_/ } @patterns; } close OUT;

        UPDATE: Removed a ) on line 5.

        As a first building block, here is a piece of code that reads from the __DATA__ segment and prints a line if one of the patterns fit. Please confirm if this is what you wanted. Some characters in the patterns need to be escaped with backslashes to make it work.

        use strict; my @patterns = ( 'unknown type\(0x134e\)', '30.6511', '\(V6.5.1 FP1\)' + ); my @array = <DATA>; foreach my $line (@array) { print $line if scalar grep { $line =~ /$_/ } @patterns; } __DATA__ no fit unknown type(0x134e) bla bla bla 30.6511 kkkkkkkkkk (V6.5.1 FP1) lllkjlkj 30.6511 klljklljk jkljkljkl
Re: Using grep to pick out Specific lines in a text file
by reisinge (Hermit) on Apr 11, 2013 at 19:21 UTC

    Hello, can you provide the input file, the desired output and the error you are getting? It would also be nice to format your code.

    Well done is better than well said. -- Benjamin Franklin

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2024-03-28 14:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found