find string, then get the next 3 lines in a file

Hi all. HPUX - /bin/sh (posix)

I am parsing a 3 field flat file, space deliminted

example data.file

acct dining mem
open 0 50
dep 50 0
close 255 0
acct plus mem
open 100 100
dep 50 0
close 323 0

I would like to find strings, then write the next 3 lines out to another file

exec < data.file
while read NAME NAME2 NAME3
do
if [ "$NAME2" = "dining" ]
then (how to I get the very next 3 lines?)

#!/bin/sh

while read NAME1 NAME2 NAME3
do
        case "$NAME2" in
        dining )
                read A
                read B
                read C
                echo $A $B $C
                ;;
        plus )
                read A
                read B
                read C
                echo $A $B $C
                ;;
        * )
                exit 1
                ;;
        esac
done <data.file

Hi.

The GNU grep can easily do this. However, AT&T offers cgrep which also can do "context" printing. One might want to use this approach for files that are large enough so that shell scripts might be too slow, or where you need additional features:

#!/bin/bash --posix

# @(#) s1       Demonstrate AT&T free cgrep for grep with context.

set -o nounset
echo

debug=":"
debug="echo"

## Use local command version for the commands in this demonstration.

echo "(Versions displayed with local utility \"version\")"
version >/dev/null 2>&1 && version bash cgrep
set -o posix
set -o | grep -i posix

echo

FILE=${1-data1}

cgrep +3 "dining" $FILE

exit 0

Producing on your data in file "data1":

% ./s1

(Versions displayed with local utility "version")
GNU bash 2.05b.0
cgrep (local) - no version provided.
posix           on

acct dining mem
open 0 50
dep 50 0
close 255 0

The AT&T source for cgrep is available at: cgrep home page -- I had no trouble downloading and compiling it on GNU/Linux, but I cannot vouch for HPUX.

It is a very useful command that can take on jobs that GNU grep normally does, plus a lot more. Best wishes ... cheers, drl

How about a one-line solution with sed?

sed -ne "/ dining /{n;p;n;p;n;p;}" data.file > output.file

All you need to do is make sure that the regex "/ dining /" is sufficently strong to avoid false matches.

Please Try following

#!/bin/sh

val=`grep -n "string" filename |awk -F":" '{print $1}'
tail +`expr $val + 1` filename |head -3

Thanks
Sridhar S:)

Yuk! That won't work at all. It assumes that the search term "string" is found only once in the datafile. If it is found more than once, then $val will have a multi-line and cause any 'expr $val' to fail with a syntax error.

Hi,

This one should be ok for you.

input:

acct dining mem
open 0 50
dep 50 0
close 255 0
acct plus mem
open 100 100
dep 50 0
close 323 0
acct dining mem
open 0 50
dep 50 0
close 255 0
acct plus mem
open 100 100
dep 50 0
close 323 0

output:

open 0 50
dep 50 0
close 255 0
open 0 50
dep 50 0
close 255 0

code:

awk '
{
if ($2=="dining")
n=NR
if (NR>=n+1 && NR<=n+3)
print
}' a > c
cat c

Try this:

sed -n "/string/{n;n;n;p;}" data.txt>data1.txt

Not sure if it could work,try it out??

awk 'c&&c--;/dining/{c=3}' filename
sed -n '/dining/{n;N;N;p;}' filename