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.
| [reply] [d/l] [select] |
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. | [reply] [d/l] |
|
well i tried what you have above and it tells me there is a syntax error at line 5
| [reply] |
|
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;
| [reply] [d/l] |
|
| [reply] |
|
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
| [reply] |
|
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;
| [reply] [d/l] |
|
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.
| [reply] |
|
| [reply] |
|
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
| [reply] [d/l] [select] |
|
| [reply] |
|
| [reply] [d/l] |
|
|
|
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
| [reply] [d/l] |