Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Outputting empty lines between grep results when running it with -C (or -B / -A)

Tags:

linux

grep

bash

Consider the following grep command over this toy input:

user@user:~$ echo -e "a\nb\nc\nd\ne" | egrep "(b|d)" -C 1 -n
1-a
2:b
3-c
4:d
5-e

Although this is quite good already as it is, I was wondering if there was some kind of trick to get an empty line between different results. Something akin to:

user@user:~$ echo -e "a\nb\nc\nd\ne" | egrep "(b|d)" -C 1 -n
1-a
2:b
3-c

3-c
4:d
5-e

Is there?

Thanks

like image 491
devoured elysium Avatar asked Oct 29 '22 22:10

devoured elysium


1 Answers

No, you can't do that with grep. You can do it with awk though:

$ echo -e "a\nb\nc\nd\ne" | awk -v c=1 '{a[NR]=$0} /(b|d)/{hits[NR]} END{ for (hit in hits) { if (x++) print "---"; for (i=hit-c;i<=hit+c;i++) print i (i==hit?":":"-") a[i] } }'
1-a
2:b
3-c
---
3-c
4:d
5-e

Obviously that's kinda lengthy to type every time you want to do this but you can use it in a shell script, e.g.:

$ cat markRanges
awk -v c="$1" -v re="$2" '
{ a[NR]=$0 }
$0 ~ re { hits[NR] }
END {
    for (hit in hits) {
        if (x++) {
            print "---"
        }
        for (i=hit-c; i<=hit+c; i++) {
            print i (i==hit?":":"-") a[i]
        }
    }
}
'

$ echo -e "a\nb\nc\nd\ne" | ./markRanges 1 '(b|d)'
1-a
2:b
3-c
---
3-c
4:d
5-e

Massage to suit...

like image 110
Ed Morton Avatar answered Dec 15 '22 02:12

Ed Morton