3

I want to grep with multiple arguments where i want to show lines in the order they appear in my source file before one argument and lines after the other argument , i e combine:

grep -A5 onestring foo.txt

and

grep -B5 otherstring foo.txt

How can this be achieved?

7
  • Run grep twice. Oct 25, 2015 at 8:55
  • Yes but then I dont know the order between the matches. I am looking at at log at want to see what happens before otherstring and after onestring. So the order is highly relevant.
    – kungjohan
    Oct 25, 2015 at 8:58
  • Hmm. ( grep -nA5 onestring foo.txt; grep -nB5 onestring foo.txt ) | sort -gu then. (Run grep twice with line numbers and uniquely sort them) Oct 25, 2015 at 9:00
  • Good idea. But will this work if I want to do this with multiple files?
    – kungjohan
    Oct 25, 2015 at 9:01
  • We can ask grep to print filenames additionally or write a shell-function with some for loops. Oct 25, 2015 at 9:02

1 Answer 1

4

In bash, ksh or zsh:

sort -gum <(grep -nA5 onestring foo.txt) <(grep -nB5 otherstring foo.txt)
# Sort by general numbers, make output unique and merge sorted files,
# where files are expanded as a result of shell's command expansion,
# FIFOs/FDs that gives the command's output

This takes O(n) time, given that grep outputs already sorted things. If process substitution is unavailable, either create temp files manually or use the O(n lgn) ( grep -nA5 onestring foo.txt; grep -nB5 otherstring foo.txt ) | sort -gu.

With grep -H we need to sort it in a more verbose way (thanks to cas):

# FIXME: I need to figure out how to deal with : in filenames then.
# Use : as separator, the first field using the default alphabetical sort, and
# 2nd field using general number sort.
sort -t: -f1,2g -um <(grep -nA5 onestring foo.txt bar.txt) <(grep -nB5 otherstring foo.txt bar.txt)
4
  • grep's output isn't sorted, rather the log file input is pre-sorted by date and time. i assume that's what you meant, but the way you wrote it isn't right.
    – cas
    Oct 25, 2015 at 9:20
  • @cas They are, in the sense of line numbers. We are using sort to put the lines back into the original order. Oct 25, 2015 at 9:21
  • btw, when using grep -H you can use sort's -t: and -k options to skip sorting on the filename etc fields.
    – cas
    Oct 25, 2015 at 9:22
  • right, so you are. missed that, my mistake
    – cas
    Oct 25, 2015 at 9:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.