Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Say I have the following file:

$ cat test

test line 1
test line 2
line without the search word
another line without it
test line 3 with two test words
test line 4

By default, grep returns each line that contains the search term

$ grep test test

test line 1
test line 2
test line 3 with two test words
test line 4

Passing grep --color will make it hilight the portion of the line that matches the search expression, but it still only returns lines that contain the expression. Is there a way to get grep to output every line in the source file, but highlight the matches?

My current terrible hack to accomplish this (at least on files that don't have 10000+ consecutive lines with no matches) is:

$ grep -B 9999 -A 9999 test test

Screenshot of the two commands

If grep can't accomplish this, is there another command-line tool that offers the same functionality? I've fiddled with ack, but it doesn't seem to have an option for it either

share|improve this question
    
Possible cross site duplicate of: stackoverflow.com/questions/981601/… The top answer is the same on both. –  Ciro Santilli Feb 16 at 14:29

4 Answers 4

up vote 72 down vote accepted
grep --color -E "test|$" yourfile

What we're doing here is matching against the $ pattern and the test pattern, obviously $ doesn't have anything to colourize so only the test pattern gets color. The -E just turns on extended regex matching.

share|improve this answer
7  
That's freaking awesome! –  gvkv Aug 12 '10 at 3:09
3  
And as a function: highlight () { grep --color -E "$1|$" $2 ; }. Usage: highlight test yourfile –  Stefan Lasiewski Oct 14 '10 at 3:48
2  
@StefanLasiewski: "$2" should also be quoted. –  Dennis Williamson Mar 17 '11 at 20:04
4  
Better could be: highlight () { grep --color -E "$1|$" "$@" } which allows files with whitespace in their names and multiple files. –  Mike DeSimone Jul 24 '11 at 5:34
9  
@MikeDeSimone - But that will also have "$1" in the files. Use highlight () { grep --color -E "$1|$" "${@:1}" } –  Chris Down Nov 17 '11 at 11:48
ack --passthru --color string file

for Ubuntu and Debian, use ack-grep instead of ack

ack-grep --passthru --color string file
share|improve this answer
1  
Oh, that's quite obviously in the man page; I'm blind. Thanks –  Michael Mrozek Aug 17 '10 at 20:03

I have the following function that I use for such things:

highlight () {
    perl -pe "s/$1/\e[1;31;43m$&\e[0m/g"
}

Internally it looks kind of ugly, it's nice and easy to use, like so:

cat some_file.txt | highlight some_word

or, for a slightly more real-world example:

tail -f console.log | highlight ERROR

You can change the colors to anything you like (which might be hard with grep--I'm not sure) by changing the 1 and 31 and 43 (after \e[) to different values. The codes to use are all over the place, but here's a quick intro: the 1 bolds the text, the 31 makes it red, and the 43 gives a yellow background. 32 or 33 would be different colors, and 44 or 45 would be different backgrounds: you get the idea. You can even make it blink (with a 5) if you're so inclined.

This doesn't use any special Perl modules, and Perl is nearly ubiquitous, so I would expect it to work just about anywhere. The grep solution is very clever, but the --color switch on grep is not available everywhere. For instance, I just tried this solution on a Solaris box running bash, and another running ksh, and my local Mac OS X machine running zsh. All worked just fine. Solaris choked on the grep --color solution, however.

Also, ack is awesome, and I recommend it to anyone who hasn't yet discovered it, but I've had some issues installing it on a few of the many servers I work on. (I forget why: I think related to Perl modules it required.)

Since I don't think I've ever worked on a Unix box that didn't have Perl installed (with the exception of embedded-type systems, Linksys routers, and such) I'd say this is pretty much a universally useable solution.

share|improve this answer

You can try:

perl -MTERM::ANSIColor -nle '/pattern/ ? print colored($_, 'color') : print' test

Not very portable however, and even if Perl is installed, you may need to download another module. In addition it will color the entire line, not just the search word.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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