4

How can I use grep to find two terms / strings in one line?
The output, or an entry in the log file, should only be made if the two terms / strings have been found.
I have made the following attempts:

egrep -n --color '(string1.*string2)' debuglog.log

In this example, everything between the two strings is marked.
But I would like to see only the two found strings marked.
Is that possible?
Maybe you could do this with another tool, I am open for suggestions.

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
webuser57
  • 171
  • 2
  • 9
  • 2
    No it's not a duplicate. OP is asking to highlight only the two matching strings. For a string, one can do it with `-o` option, but for two it's not. – iamauser Mar 06 '18 at 14:50
  • 1
    Okay, I removed duplicate. – Cyrus Mar 06 '18 at 14:53
  • 1
    Use awk but please post some sample data and expected output to go with it. – James Brown Mar 06 '18 at 15:05
  • 1
    It is not a duplicate. OP tries not only match the strings but also color them. There is no answer for that in the referred entry. – Dzienny Mar 06 '18 at 16:31
  • Possible duplicate of [How to use grep to match string1 AND string2?](https://stackoverflow.com/q/4487328/608639) – jww Mar 13 '19 at 04:47

4 Answers4

3

The simplest solution would be to first select only the lines that contain both strings and then grep twice to color the matches, eg:

egrep 'string1.*string2|string2.*string1' |
    egrep -n --color=always 'string1' | egrep --color 'string2'

It is important to set color to always, otherwise the grep won't output the color information to the pipe.

Dzienny
  • 3,295
  • 1
  • 20
  • 30
2

Here is single command awk solution that prefixes and suffixes matched strings with color codes:

awk '/string1.*string2/{
gsub(/string1|string2/, "\033[01;31m\033[K&\033[m"); print}' file
anubhava
  • 761,203
  • 64
  • 569
  • 643
1

I know some people will disagree, but I think the best way is to do it like this :

Lets say this is your input :

$ cat > fruits.txt
apple banana
orange strawberry
coconut watermelon
apple peach

With this code you can get exactly what you need, and the code looks nicer and cleaner :

awk '{ if ( $0 ~ /apple/ && $0 ~ /banana/ ) 
       { 
         print $0
       } 
    }' fruits.txt

But, as I said before, some people will disagree as its too much typing. ths short way with grep is just concatenate many greps , e.g. :

grep 'apple' fruits.txt | grep 'banana'

Regards!

Matias Barrios
  • 4,674
  • 3
  • 22
  • 49
0

I am a little confused of what you really want as there was no sample data or expected output, but:

$ cat foo
1
2
12
21
132
13

And the awk that prints the matching parts of the records:

$ awk '
/1/ && /2/ {
    while(match($0,/1|2/)) {
        b=b substr($0,RSTART,RLENGTH)
        $0=substr($0,RSTART+RLENGTH)
    }
    print b
    b=""
}' foo
12
21
12

but fails with printing overlapping matches.

James Brown
  • 36,089
  • 7
  • 43
  • 59