Operating System - HP-UX
1824171 Members
2671 Online
109669 Solutions
New Discussion юеВ

Perl: Handling multiple lines

 
dave.s
Advisor

Perl: Handling multiple lines

Im trying to cleanup a few errors in swverify using perl. I am able to handle the errors when they are on one complete line. Though, swverify likes to post a majority of the problems on mulitple lines.

What I have (broken lines)

WARNING: Directory "/usr/share/man/cat7.Z" should have
owner,uid "bin,2" but the actual owner,uid is "root,0".

What I want (complete line)

WARNING: Directory "/usr/share/man/cat7.Z" should have owner,uid "bin,2" but the actual owner,uid is "root,0".

Is there anyway to do this in perl?

2 REPLIES 2
H.Merijn Brand (procura
Honored Contributor

Re: Perl: Handling multiple lines

like this?

m/^warning\b/i and chomp;

that'll remove the newline from lines starting with the word warning (case insensitive), and thus join with the next line. Maybe a bit more elegant would be:

if (m/^warning\b/i) {
chomp; # remove trailing newline
s/$/ /; # add a space
$_ .= scalar <>; # join the next available line to the current
}

but as always, TIMTOWTDI

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
Hein van den Heuvel
Honored Contributor

Re: Perl: Handling multiple lines

Un(?)fortunately I do not know all to pssoble ways a swverify log might look like, but I doubt all lines with WARNING are split, and I doubt only lines with WARNING are split. Maybe there are ERROR: lines which are split also?

So I suspect the prior solution is not good enough. It will merrily join a complete, non-split, warningn with the next warning.
We need more info to know how to best solve this.
We humanoids readily 'see' whether a line is a continuation or a fresh start. The better you can capture that in an algoritme, the better solution you can build.

As a simple example, the single sample line SUGGEST there migh be a space at the end of a split line. Is there always?
If so, a solution might be:

perl -p "perl -pe "m/^warning\b.* $/i and chomp;" split.log > fixed.log

And to deal with ERRORS and what else you might make that:

perl -p "perl -pe "m/^[A-Z]* $/ and chomp;" split.log > fixed.log


Maybe the dangling space at the end does not exist, but each non-split line should start with an uppercase character. In that case the script will have to look back.
The brute force, solution is to slurp the file into an array and process.
But you coudl postpone dealing with a line until the next is seen. Something like

---- join.pl ---
while (<>) {
if (/^[A-Z]/ or eof) {
# Process line now. Here just print.
print "$line";
# prep for next
$line = $_;
} else {
# Found a line not starting with uppercase character
# Assume it was a continuation
chomp $line;
$line .= " " . $_;
}
}
# Process final line:
print "Final: $line";
-------------
$ perl join.pl split.log > fixed.log


hth,
Hein.