in reply to How can I solve this text manipulation problem with perl?
I would start by reading each line, ignoring it if it is blank/unrecognized, swapping it for the new header if it was a header, and if it looks like data, splitting it up into a list of values using split on whitespace.
Add any new values needed, such as the date from filename, and then use printf to write it back out in the desired order with fixed width fields.
Seems I got a bit carried away tho:
#Fill in ...'s with more code as needed. use strict; use warnings; my $filename = 'somelog.log'; my $outfilename = 'mungedlog.log'; my $oldHeader = ' id pool type rid rset + min max size used load'; # Define the output format, and where the data comes from my @newFormatColumns = ( {title=>'date', length=>10, format='s', splitDataIndex=>15}, ... {title=>'id', length=>3, format=>'d', splitDataIndex=>0}, ... ); # Build new header lines automagically based on above AoH my $newHeaderFormat; $newHeaderFormat .= '%'. $_->{length} . 's' for @newFormatColumns; my $newHeader = sprintf($newHeaderFormat, ( map {$_->{title}} @newForm +atColumns)); open my $iFH, '<', $filename or die "Can't open '$filename' because: $ +!\n"; open my $oFH, '>', $outfilename or die "Can't open '$outfilename' beca +use: $!\n"; #Grind through file until done. while (my $line = <$fh>) { chomp $line; if ($line =~ /.../) # looks like data { # Munge data lines into new format # grab data from the line read my @data = split /\s/, $line; # add new values to the end push @data, 'new values here', 'here', 'and here'; # Build new line of data $line = ''; # this is basically a set of: # $line .= sprintf ("%20s", $data[1]); # where $data[1] is the pool string for example. # and the '20', the 's' and the '1' all come # from the AoH table declared at the beginning. $line .= sprintf ("%$_->{length}$_->{format}", $data[$_->{splitDat +aindex}]) for @newFormatColumns; }elsif ($line eq $oldHeader){ # Change header lines $line = $newHeader; }else{ # Leave unrecognized lines alone. } # And don't forget to print it all to the output file. print $oFH "$line\n"; }
|
|---|