Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!nrl-cmf!ames!ncar!unmvax!tut.cis.ohio-state.edu!bloom-beacon!bu-cs!purdue!decwrl!sun!pitstop!sundc!seismo!uunet!mcvax!hp4nl!botter!star.cs.vu.nl!maart From: maart@cs.vu.nl (Maarten Litmaath) Newsgroups: comp.unix.questions Subject: Re: context-grep Keywords: grep Message-ID: <2017@piraat.cs.vu.nl> Date: 8 Feb 89 14:40:13 GMT References: <9176@burdvax.PRC.Unisys.COM> Organization: V.U. Informatica, Amsterdam, the Netherlands Lines: 145 lang@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>] [--] []" 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@cs.vu.nl, mcvax!botter!maart