I am trying to grep for 5 lines before and after a match. Since I am using AIX I do not have the GNU feature of :
grep -B 5 -A 5 pattern file
Is there a way to do this with grep, awk, perl, sed, something else? Can I please get a one liner? I am trying to do this across multiple servers.
@cokedude , any luck searching these forums for similar topics? It's been covered numerous times...
An attempt with awk:
awk 'del=(a&&a--) {print; da=!a} $0~pattern{if (da) {print "--"; da=0} a=A; if (B) {for(i=NR; i<B+NR; i++) if((i%B) in b) print b[i%B]} {print; da=1}} (B) {if (del) delete b[NR%B]; else b[NR%B]=$0}' B=5 A=2 pattern=test filename
to emulate
grep -B5 -A2 test filename
drl
July 21, 2021, 3:47pm
7
Hi.
A few of the suggestions in Grep -C option not available - #4 by CarloM will allow a single command line to emulate GNU grep, but only after you install the alternate grep-work-alike codes, such as peg or cgrep.
Best wishes ... cheers, drl
This works when running a command on the current server. I have noticed when I try to run this on a remote server it does not work.
ssh server "awk 'del=(a&&a--) {print; da=! a} $0~pattern{if (da) {print "--"; da=0} a=A; if (B) {for(i=NR; i<B+NR; i++) if((i%B) in b) print b[i%B]} {print; da=1}} (B) {if (del) delete b[NR%B]; else b[NR%B]=$0}' B=5 A=2 pattern=Successful file"
bash: !a}: event not found
I tried to backslash it.
ssh server "awk 'del=(a&&a--) {print; da=\!a} $0~pattern{if (da) {print "--"; da=0} a=A; if (B) {for(i=NR; i<B+NR; i++) if((i%B) in b) print b[i%B]} {print; da=1}} (B) {if (del) delete b[NR%B]; else b[NR%B]=$0}' B=5 A=2 pattern=Successful file"
syntax error The source line is 1.
The error context is
del=(a&&a--) {print; >>> da=\ <<< !a} bash~pattern{if (da) {print --; da=0} a=A; if (B) {for(i=NR; i<B+NR; i++) if((i%B) in b) print b[i%B]} {print; da=1}} (B) {if (del) delete b[NR%B]; else b[NR%B]=bash}
awk: The statement cannot be correctly parsed.
The source line is 1.
I tried set +H like this site suggested.
ssh server "set +H; awk 'del=(a&&a--) {print; da=! a} $0~pattern{if (da) {print "--"; da=0} a=A; if (B) {for(i=NR; i<B+NR; i++) if((i%B) in b) print b[i%B]} {print; da=1}} (B) {if (del) delete b[NR%B]; else b[NR%B]=$0}' B=5 A=2 pattern=Successful file"
ksh: +H: bad option(s)
Is there a way to get this to run on a remote server?
I have been unable to convince the senior admin to install this.
ssh host command args can give you a quoting headache, because there is the local ssh command where the local shell does a evaluation/dequoting, and then the remote command where the remote shell does another evaluation/dequoting.
Here comes a solution.
Save the command to a file, for example mygrep.sh in the current directory. Let the script pass the script arguments:
#!/bin/sh
awk 'del=(a&&a--) {print; da=!a} $0~pattern{if (da) {print "--"; da=0} a=A; if (B) {for(i=NR; i<B+NR; i++) if((i%B) in b) print b[i%B]} {print; da=1}} (B) {if (del) delete b[NR%B]; else b[NR%B]=$0}' "$@"
Then run the ssh as follows:
ssh host /bin/sh -s B=5 A=2 pattern=Successful file < mygrep.sh
The ssh remote shell runs another /bin/sh where -s tells to read commands from stdin and take the following arguments.
The stdin comes from the local mygrep.sh file.