For Programmers: Free Programming Magazines  


Home > Archive > AWK > December 2005 > Emulation of gnu grep's -N option









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Emulation of gnu grep's -N option
James

2005-11-29, 6:56 pm

How to emulate gnu grep's -N option with awk,
listing N lines before and after the matched lines?

e.g.
grep -3 string file

This will be useful where gnu grep is not installed.
Thanks in advance.

James

Ed Morton

2005-11-29, 6:56 pm

James wrote:
> How to emulate gnu grep's -N option with awk,
> listing N lines before and after the matched lines?
>
> e.g.
> grep -3 string file
>
> This will be useful where gnu grep is not installed.
> Thanks in advance.
>
> James
>


Here's how to emulate -A and -B, its a trivial tweak to make it work for
the simpler -N:

------------------
function nextIdx(idx) { return ( (idx % bufSize) + 1) }

function saveBuf(txt) { idx = nextIdx(idx); buf[idx] = txt }

function prtBuf() {
for (i=0; i<bufSize; i++) {
j = nextIdx(idx + i)
if (j in buf) print buf[j]
}
}

BEGIN{ bufSize = B + 1 }

{ saveBuf($0) }

found { found--; print }

$0 ~ pat { found = A; prtBuf() }
---------------

Save it in a file called, say "buf.awk" then run it as:

awk -v pat="foo" -v A=3 -v B=2 file

to search for "foo" plus the 2 lines before and 3 lines after it. The
above is just off the top of my head. I suspect it may have problems if
there's multiple ocurrences of foo in the file.

Regards,

Ed.

James

2005-12-01, 7:00 pm


Ed Morton wrote:
>
> Here's how to emulate -A and -B, its a trivial tweak to make it work for
> the simpler -N:
>
> ------------------
> function nextIdx(idx) { return ( (idx % bufSize) + 1) }
>
> function saveBuf(txt) { idx = nextIdx(idx); buf[idx] = txt }
>
> function prtBuf() {
> for (i=0; i<bufSize; i++) {
> j = nextIdx(idx + i)
> if (j in buf) print buf[j]
> }
> }
>
> BEGIN{ bufSize = B + 1 }
>
> { saveBuf($0) }
>
> found { found--; print }
>
> $0 ~ pat { found = A; prtBuf() }
> ---------------
>
> Save it in a file called, say "buf.awk" then run it as:
>
> awk -v pat="foo" -v A=3 -v B=2 file
>
> to search for "foo" plus the 2 lines before and 3 lines after it. The
> above is just off the top of my head. I suspect it may have problems if
> there's multiple ocurrences of foo in the file.
>


Thanks for your reply.
I have added line numbers and removed duplicate text.

Usage: awk -v pat="foo" -v N=3 -f script.awk file

function nextIdx(idx) { return ( (idx % bufSize) + 1) }
function saveBuf(txt) { idx = nextIdx(idx); buf[idx] = txt; nr[idx] =
NR }
function prtBuf() {
for (i=0; i<bufSize - 1; i++) {
j = nextIdx(idx + i)
if (j in buf) print nr[j], ": ", buf[j]
}
print NR, "->", $0
}

BEGIN{ A = B = N; bufSize = B + 1 }

! found { saveBuf($0) }
found && $0 !~ pat { found--; print NR, ": ", $0 }
$0 ~ pat { found = A; prtBuf(); delete buf }


James

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com