Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^2: Using grep to pick out Specific lines in a text file

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


in reply to Re: Using grep to pick out Specific lines in a text file
in thread Using grep to pick out Specific lines in a text file

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;}

Replies are listed 'Best First'.
Re^3: Using grep to pick out Specific lines in a text file
by davido (Cardinal) on Apr 11, 2013 at 19:40 UTC

    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

Re^3: Using grep to pick out Specific lines in a text file
by hdb (Monsignor) on Apr 11, 2013 at 19:51 UTC

    ...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.

      well i tried what you have above and it tells me there is a syntax error at line 5

        Here is a version that tries to heed davido's advice:

        use strict; use warnings; use lib "/Library/Perl/5.10.0/"; use autodie; my @patterns = ( 'unknown type\(0x134e\)', '30.6511', '\(V6.5.1 FP1\)' + ); open FILE, "<", "data/04102013_loginlogs.txt" or die "Cannot open inpu +t file.\n"; open OUT, ">>", "output.txt" or die "Cannot open output file.\n"; while( my $line=<FILE> ) { print OUT $line if scalar grep { $line =~ /$_/ } @patterns; } close OUT; close FILE;

        One ) too much. Sorry. I will correct it.

      Ok so this did search this time, My issue is that i need to pull the line that has all of the following true. unknown type(0x134e) 30.6511 (V6.5.1 FP1)

      Here is a line from the data file

      01 XXXXXXXX 10/Apr/13 01:13:10 unknown type(0x134e) 30.6511 (V6.5.1 FP1) Singer 192.168.1.1

        That is even easier. Just one regex.

        use strict; use warnings; use lib "/Library/Perl/5.10.0/"; use autodie; open FILE, "<", "data/04102013_loginlogs.txt" or die "Cannot open inpu +t file.\n"; open OUT, ">>", "output.txt" or die "Cannot open output file.\n"; while( my $line=<FILE> ) { print OUT $line if $line =~ /unknown type\(0x134e\)\s+30\.6511\s+\(V +6\.5\.1 FP1\)/; } close OUT; close FILE;

      Perfect, that worked great. Now that it is working i found another issue. In this where "singer" is i pulled 23 different occurances, i only need to print singer in my out put. That tells me that it does show up in the data log. And Singer does change to multiple values.

        Think hash

        If you didn't program your executable by toggling in binary, it wasn't really programming!

        This is based on the assumption that after ...30.6511 (V6.5.1 FP1) comes one or more spaces, then a word (that you are looking for), some more spaces, an IP address, possibly some spaces before the end of line. You need to modify the regex should this assumption not hold.

        use strict; use warnings; use lib "/Library/Perl/5.10.0/"; use autodie; open FILE, "<", "data/04102013_loginlogs.txt" or die "Cannot open inpu +t file.\n"; open OUT, ">>", "output.txt" or die "Cannot open output file.\n"; my %found; while( my $line=<FILE> ) { $found{$1}++ if( $line =~ /unknown type\(0x134e\)\s+30\.6511\s ++\(V6\.5\.1 FP1\)\s+(.*)\s+\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s*$/ ); } print join( "|", keys %found), "\n"; close OUT; close FILE;

        I have used this test file:

        01 XXXXXXXX 10/Apr/13 01:13:10 unknown type(0x134e) 30.6511 (V6.5.1 FP +1) Singer 192.168.1.1 01 XXXXXXXX 10/Apr/13 01:13:10 unknown type(0x134e) 30.6511 (V6.5.1 FP +1) Singer 192.168.1.1 01 XXXXXXXX 10/Apr/13 01:13:10 unknown type(0x134e) 30.6511 (V6.5.1 FP +1) Runner 192.168.1.10 ddddd 01 XXXXXXXX 10/Apr/13 01:13:10 unknown type(0x134e) 30.6511 (V6.5.1 FP +1) Singer 192.168.1.1 01 XXXXXXXX 10/Apr/13 01:13:10 unknown type(0x134e) 30.6511 (V6.5.1 FP +1) Dancer 192.168.1.1 ddddd ffffff 01 XXXXXXXX 10/Apr/13 01:13:10 unknown type(0x134e) 30.6511 (V6.5.1 FP +1) Singer 192.168.1.1 01 XXXXXXXX 10/Apr/13 01:13:10 unknown type(0x134e) 30.6511 (V6.5.1 FP +1) Singer 192.168.1.1 01 XXXXXXXX 10/Apr/13 01:13:10 unknown type(0x134e) 30.6511 (V6.5.1 FP +1) Singer 192.168.1.1

      Works great but now i think i want it to look different... woulld look like the blow

      30.6511 (V6.5.1 FP1) KALLATOM@de.ibm.com 255.255.255.255 (then a count of how may timesit showed up)

        Guess what! That's what $found{$1}++ is for. Just print not only the keys but also the values of hash %found.

Re^3: Using grep to pick out Specific lines in a text file
by hdb (Monsignor) on Apr 11, 2013 at 19:46 UTC

    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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1028215]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (3)
As of 2024-04-26 00:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found