6

grep returns just the line where it matched the regex and often what I want to really see is a few (say 2) lines above and below the matched one. Is there a simple way to achieve it?

EDIT: OS: Ubuntu based Bodhi Linux. As mentioned in comments, -C does not work in vanilla but its GNU grep in my case.

2 Answers2

12

From man grep:

Context Line Control

-A NUM, --after-context=NUM

Print NUM lines of trailing context after matching lines. Places a line containing a group separator (--) between contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.

-B NUM, --before-context=NUM

Print NUM lines of leading context before matching lines. Places a line containing a group separator (--) between contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.

-C NUM, -NUM, --context=NUM

Print NUM lines of output context. Places a line containing a group separator (--) between contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.

See how easy that was? man is your friend.

goldilocks
  • 87,661
  • 30
  • 204
  • 262
0

Using (more portable) :

awk '
    {
        arr[NR]=$0
    }
    END{
        for (i=0;i<=NR;i++) {
            if (arr[i] ~ grep){
                for (j=i-count; j<=i+count; j++) {
                    print arr[j]
                }
            }
        }
    }
' grep=kdm count=4 /etc/passwd

I grep user kdm againts /etc/passwd with 4 lines before/after the match

In a script :

#!/bin/sh

awk '
    {
        arr[NR]=$0
    }
    END{
        for (i=0;i<=NR;i++) {
            if (arr[i] ~ grep){
                for (j=i-count; j<=i+count; j++) {
                    print arr[j]
                }
            }
        }
    }
' grep="$1" count="$2" "$3"

Usage :

./contextgrep <pattern> <count> <file>