context-grep

Maarten Litmaath maart at cs.vu.nl
Thu Feb 9 00:40:13 AEST 1989


lang at pearl.PRC.Unisys.COM (Francois-Michel Lang) writes:
\I think I can use awk to do a watered-down version of this,

How about `sed'? I think Leo de Wit [a.k.a. Mr. Sed] will have some remarks
about `cgrep', but it's a start.

#! /bin/sh

# cgrep		- context grep
#
# grep pattern plus surrounding lines
# @(#)cgrep 1.1 89/01/18 Maarten Litmaath
#
# example: "cgrep -5 +0 '^{' *.c" shows all function headers in the C sources,
# with (max.) 5 lines preceding the `{', followed by 0 lines (no line will be
# printed twice; there might not be as many contextual lines as requested)
# only the names of files with matches are printed, followed by a line of
# `====='; each match is separated from the following by a line of `-----'
# cgrep can be used as a filter; the file name will be `STDIN'
# the `--' option can be used to `protect' a pattern starting with `-'

usage="Usage: cgrep [-<# before>] [+<# after>] [--] <regexp> [<files>]"

if [ $# = 0 ]
then
	echo "$usage"
	exit 1
fi

b=2
a=2

while :
do
	case $1 in
		--)
			shift
			break
			;;
		-*)
			b=`echo "x$1" | sed s/..//`
			shift
			;;
		+*)
			a=`echo "x$1" | sed s/..//`
			shift
			;;
		*)
			break
	esac
done

if [ $# = 0 ]
then
	echo "$usage"
	exit 1
fi

pattern=`echo "$1" | sed 's-/-\\\/-'`
shift

[ x$b = x ] && b=1
[ x$a = x ] && a=1

if [ $b = 0 ]
then
	branch=b
else
	case "$pattern" in
		\^*)
			pattern=`echo "$pattern" | sed 's/./\\\n/'`
	esac
fi

while [ $b -gt 0 ]
do
	before=".*\n$before"
	b=`expr $b - 1`
done
	
while [ $a -gt 0 ]
do
	after="n;p;$after"
	a=`expr $a - 1`
done

if [ $# = 0 ]
then
	files=STDIN
	set dummy
else
	files="$*"
	set dummy $*
fi

umask 077

for i in $files
do
	shift

	sed -n "
			/$pattern/{
				p
				$after
				a\\
					-----
				b
			}
			$branch
		: L0
			N
			/$pattern/{
				p
				$after
				a\\
					-----
				b
			}
			/$before.*/!b L0
		: L1
			s/[^\n]*\n//
			N
			/$pattern/{
				p
				$after
				a\\
					-----
				b
			}
			b L1
		" $1 > /tmp/cgrep.$$

	if [ -s /tmp/cgrep.$$ ]
	then
		echo $i
		echo =====
		cat /tmp/cgrep.$$
	fi
done

/bin/rm -f /tmp/cgrep.$$
-- 
 "I love it                            |Maarten Litmaath @ VU Amsterdam:
          when a plan comes together." |maart at cs.vu.nl, mcvax!botter!maart



More information about the Comp.unix.questions mailing list