unixawkgrepaix

I want to zgrep from .debug.gz and get lines before and after the string


I'm logging in to my company's IBM AIX system and the grep there isn't GNU and it's the default one and it doesn't support the options -B, -A, -C. I found this workaround for normal grep:

grep -n '123456' file.debugz.gz |
cut -d':' -f1 |
xargs -n1 -I % awk 'NR<=%+3 && NR>=%-2' file.debugz.gz

However I'm trying to use zgrep or zegrep to get the values from inside a .debug.gz file which has a lot of data in it and big file size, so instead of gunzip and searching manually in each .debug.gz file I want to use the above command but it doesn't work with zgrep or zegrep.

I want to show a context of 30 lines above and below the matching line.

Please note that I cannot gunzip the file, I want to grep what's inside without any scripts or gunzip.


Solution

  • You could use awk to emulate the unsupported -A / -B options (-C seems like a shortcut for specifying both).

    For example:

    Optionally, keep track of when to print -- divisions.

    mygrep(){
        awk -v B=$1 -v A=$2 -v RE=$3 '
            $0~RE {
                if (!after) {
                    if ( previous && (NR-B)-(previous+A)>1 )
                        print "--"
                    for (before = (NR-B); before<NR; ++before)
                        if ( before > (previous+A) )
                            print buf[ before%B ]
                }
                after = A+1
                previous = NR
            }
            after { print; --after }
            +B { buf[ NR%B ] = $0 }
        '
    }
    

    Sample usage:

    $ seq 100 | mygrep 1 2 '5[179]$'
    50
    51
    52
    53
    --
    56
    57
    58
    59
    60
    61
    $
    

    You still need a way for awk to access the decompressed data. gunzip -c can write to stdout/pipe without unpacking the original file.

    So you could do something like:

    gunzip -c file.debug.gz | mygrep 30 30 '123456'