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
|
|
|
| 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.
| |
|
|
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
|
|
|
|
|