1753500 Members
4545 Online
108794 Solutions
New Discussion юеВ

scripting help

 
SOLVED
Go to solution
Rick Garland
Honored Contributor

scripting help

Hi all:

Been banging my head on this one and I can't find the right touch.

I have output from a command that produces the following format;

Handle
another line
another line
another line

Handle
System Information
line 1
line 2
line 3
line 4

Handle
another line
another line
another line
another line

Handle
etc...

What I am wanting to do is print everything between the lines of Handle but only if the pattern of System Information is matched. The rest of the data I do not want.

I did come up with this and it works OK, but I know there is a better solution.
awk 'BEGIN { RS = "System Information" } END { RS = "" } {print $1, $2, $3, "\n" $4, $5, $6}'

Like I said, this works OK but if the number of variables/lines changes then the print changes. What I really want is to print all lines (line 1, line 2, line 3 line n, ...) regardless of the number of lines.

The shell can be either ksh or bash.

Many thanks
9 REPLIES 9
Rick Garland
Honored Contributor

Re: scripting help

And what the heck, how about perl as well.
James R. Ferguson
Acclaimed Contributor
Solution

Re: scripting help

Hi Rick:

# perl -nle '$/="";print if m/Handle/ && m/System/' file

Regards!

...JRF...
Rick Garland
Honored Contributor

Re: scripting help

Thanks JRF!
Any thing for shell (using awk, sed, or something)?

Rick Garland
Honored Contributor

Re: scripting help

One thing I do see I do not want with the perl syntax is that I do not want to print any of the lines after the next Handle. I only want the line 1, line 2, line 3 - the rest of the output (another line) I do not want.
Rick Garland
Honored Contributor

Re: scripting help

Found my answer with awk, at least.
awk '/System Information/,/Handle/' file

This will print the line 1 line 2 line 3 line 4 line n...

James R. Ferguson
Acclaimed Contributor

Re: scripting help

Hi (again) Rick:

OK, you can do the same in 'awk' with:

# awk 'BEGIN{RS=""};{if (/Handle/ && /System/) {print}}' file

> I only want the line 1, line 2, line 3 - the rest of the output (another line) I do not want.

That changes things a bit since in either the Perl or 'awk' we have used the blank line to signal a record's endpoint.

One kludge way would be to pipe the output of the 'awk' or 'perl' script to 'head -5'.

Regards!

...JRF...



Patrick Wallek
Honored Contributor

Re: scripting help

How about a shell script with no awk or anything:

#!/usr/bin/sh

while read LINE
do
if [[ "${LINE}" = "Handle" ]] ; then
HANDLE=1
elif [[ "${LINE}" = "System Information" ]] ; then
echo "Handle"
echo ${LINE}
SYSINF=0
HANDLE=0
elif [[ "${SYSINF}" = "0" && "${HANDLE}" = "0" && "${LINE}" != "" ]] ; then
echo ${LINE}
fi
done < testfile

Running this, with your example data yields:

$ sh ./test.sh
Handle
System Information
line 1
line 2
line 3
line 4
$
Rick Garland
Honored Contributor

Re: scripting help

I like that to!

Amy thanks James and Patrick

James R. Ferguson
Acclaimed Contributor

Re: scripting help

Hi (again) Rick:

A bit better than the pipe to 'head' to snip any additional lines you don's want is this variation. It also handles repetitive blocks that match:

# perl -nle '$/="";if (m/Handle/ && m/System/) {@a=m/(.+?$)(.+?$)(.+?$)(.+?$)(.+?$)/sm and print @a}' file

Regards!

...JRF...