11

For my work, I'm frequently searching for patterns in files. Generally I use the grep --color=auto to color the search pattern. Now when I'm searching for multiple patterns, all of which should be present in a line, I use grep pattern1 file|grep pattern2|grep pattern3 or awk '/pattern1/&&/pattern2'. But this way, in grep I lose the coloring which is highly helpful for me, or in awk, I don't know any way to color only the pattern string. When it becomes too troublesome, I use grep pattern1 file|grep pattern2|grep pattern3|grep -E "pattern1|pattern2|pattern3".

So is there any way in grep to mention multiple patterns in and condition? ( I think regular expressions should support it, but could not find any, specially the ordering of patterns are not fixed)

Or is there any way to color print the awk search patterns?

Any short compact approach is welcome (for I will be using many times a day )

Frank Schmitt
  • 30,195
  • 12
  • 73
  • 107
abasu
  • 2,454
  • 19
  • 22
  • 1
    see my answer on http://stackoverflow.com/a/6540890/297323 – Fredrik Pihl Apr 11 '13 at 09:39
  • @FredrikPihl I searched with awk color output earlier, all of them are actually formatting a field, not a pattern. So i can make the 2nd field in green if i want, but i don't know if my pattern is going to come in second field or 3rd field. What i want is that pattern should come in green, irrespective of where it is coming – abasu Apr 11 '13 at 09:52

3 Answers3

10

You can use --color=always when piping from grep to retain color:

grep pat1 --color=always | grep pat2
perreal
  • 94,503
  • 21
  • 155
  • 181
  • Thanks @perreal, It saved the day :) . But still, i'm curious, Is there any way in grep to combine patterns in "and" condition? If "or" condition is present, why "and" is not present ? I am not talking about pipe the output, but a single grep, which will look for strings which contains all the pattern given, in any order – abasu Apr 11 '13 at 10:23
  • 1
    the way to do and is 1) piping, 2) using something like `grep -e 'pat1.*pat2' -e 'pat2.*pat1' input`. Perhaps it is missing because it is redundant (you cannot `or` with pipes). – perreal Apr 11 '13 at 10:27
6

You could build your own shell script/function using awk and escape codes:

Given the file Awk color text the following will print the matched word Awk in cyan:

$ awk '/Awk/{gsub(/Awk/,"\033[1;36m&\033[1;000m");print}' file
Awk color test

This principle can easily be extended for multiple patterns added This line ends here to line one.

$ awk '/Awk/&&/This/{gsub(/Awk|This/,"\033[1;36m&\033[1;000m");print}' file
Awk color test This line ends here.

Check out here for some more information on shell colours.

Chris Seymour
  • 83,387
  • 30
  • 160
  • 202
  • 1
    Thanks @sudo_O, I knew about the gsub, but never thought of using it this way. It perfectly answers the second question. – abasu Apr 11 '13 at 11:25
0

You could also use curly braces for parameter expansion:

grep --color=always -e{pat1,pat2}

which effectively is the same as:

grep --color=always -e foo -e bar

Note this will return results with pat1 AND/OR pat2.

(I don't have enough reputation points to add this post as a comment)

trellem
  • 31
  • 5