Reputation: 111
I have multiple log files that looks like dmesg output. I need to parse and store certain result from all these files into one single output file. Ex Input file1:
.....
Started 1399343129
KbPerSec 1222
KiloBytes 9302938
Status 83
StorageUNit unitname
Ended 1399473434
.......
Output file:
1399343129 1222 9302938 83 unitname 1399473434
<input file2 numbers>
<input file3 numbers>
.....
So, I use grep, and split the grep result to get the number I want. Here is what my code looks like.
<TRY>
is my file handle.
my (@grepres, @splitres);
my ($size, $start, $bw);
if(@grepres=grep{/KbPerSec/} <TRY>){
@splitres=split(' ',$grepres[0]);
$bw=$splitres[1];
print "1. $bw\n";
}
if(@grepres=grep{/Started/} <TRY>){
@splitres=split(' ',$grepres[0]);
$start=$splitres[1];
print "$start\n";
}
...
Upvotes: 0
Views: 2629
Reputation: 6573
Here is a possible approach that depends on the fields being in the same order from record to record.
Update: Changed the end condition match.
#!/usr/bin/perl
use strict;
use warnings;
my @data;
while (<DATA>) {
if (/^Started/ .. /^Ended/) {
push @data, /^\S+ (.+)$/;
print join(" ", splice @data), "\n" if /^Ended/;
}
}
__DATA__
.....
Started 1399343129
KbPerSec 1222
KiloBytes 9302938
Status 83
StorageUNit unitname
Ended 1399473434
.......
Prints
1399343129 1222 9302938 83 unitname 1399473434
Upvotes: 1
Reputation: 118605
<TRY>
in list context consumes all the data in the TRY
filehandle, making subsequent calls to <TRY>
return empty. If you want to reuse the data in the filestream, eithera. save the stream to a variable
my @try = <TRY>;
if ( grep ..., @try ) {
...
}
if ( grep ..., @try ) {
...
}
b. reopen the file or seek
back to the beginning
open TRY, '<', $try_file
...
if (grep ..., <TRY>) {
...
}
close TRY;
open TRY, '<', $try_file
if (grep ..., <TRY>) {
...
}
open TRY, '<', $try_file
...
if (grep ..., <TRY>) {
...
}
seek TRY, 0, 0; # reset cursor position to start of file
if (grep ..., <TRY>) {
...
}
Upvotes: 1