Highlight text similar to grep, but don't filter out text

LinuxGrepCommand Line-Interface

Linux Problem Overview


When using grep, it will highlight any text in a line with a match to your regular expression.

What if I want this behaviour, but have grep print out all lines as well? I came up empty after a quick look through the grep man page.

Linux Solutions


Solution 1 - Linux

Use ack. Checkout its --passthru option here: ack. It has the added benefit of allowing full perl regular expressions.

$ ack --passthru 'pattern1' file_name

$ command_here | ack --passthru 'pattern1'

You can also do it using grep like this:

$ grep --color -E '^|pattern1|pattern2' file_name

$ command_here | grep --color -E '^|pattern1|pattern2'

This will match all lines and highlight the patterns. The ^ matches every start of line, but won't get printed/highlighted since it's not a character.

(Note that most of the setups will use --color by default. You may not need that flag).

Solution 2 - Linux

You can make sure that all lines match but there is nothing to highlight on irrelevant matches

egrep --color 'apple|' test.txt 

Notes:

  • egrep may be spelled also grep -E
  • --color is usually default in most distributions
  • some variants of grep will "optimize" the empty match, so you might want to use "apple|$" instead (see: https://stackoverflow.com/a/13979036/939457)

Solution 3 - Linux

EDIT:

This works with OS X Mountain Lion's grep:

grep --color -E 'pattern1|pattern2|$'

This is better than '^|pattern1|pattern2' because the ^ part of the alternation matches at the beginning of the line whereas the $ matches at the end of the line. Some regular expression engines won't highlight pattern1 or pattern2 because ^ already matched and the engine is eager.

Something similar happens for 'pattern1|pattern2|' because the regex engine notices the empty alternation at the end of the pattern string matches the beginning of the subject string.

[1]: http://www.regular-expressions.info/engine.html

FIRST EDIT:

I ended up using perl:

perl -pe 's:pattern:\033[31;1m$&\033[30;0m:g'

This assumes you have an ANSI-compatible terminal.

ORIGINAL ANSWER:

If you're stuck with a strange grep, this might work:

grep -E --color=always -A500 -B500 'pattern1|pattern2' | grep -v '^--'

Adjust the numbers to get all the lines you want.

The second grep just removes extraneous -- lines inserted by the BSD-style grep on Mac OS X Mountain Lion, even when the context of consecutive matches overlap.

I thought GNU grep omitted the -- lines when context overlaps, but it's been awhile so maybe I remember wrong.

Solution 4 - Linux

You can use my highlight script from https://github.com/kepkin/dev-shell-essentials

It's better than grep cause you can highlight each match with it's own color.

$ command_here | highlight green "input" | highlight red "output"

enter image description here

Solution 5 - Linux

Since you want matches highlighted, this is probably for human consumption (as opposed to piping to another program for instance), so a nice solution would be to use:

less -p <your-pattern> <your-file>

And if you don't care about case sensitivity:

less -i -p <your-pattern> <your-file>

This also has the advantage of having pages, which is nice when having to go through a long output

Solution 6 - Linux

You can do it using only grep by:

  1. reading the file line by line
  2. matching a pattern in each line and highlighting pattern by grep
  3. if there is no match, echo the line as is

which gives you the following:

while read line ; do (echo $line | grep PATTERN) || echo $line  ; done < inputfile

Solution 7 - Linux

If you want to print "all" lines, there is a simple working solution:

grep "test" -A 9999999 -B 9999999
  • A => After
  • B => Before

Solution 8 - Linux

If you are doing this because you want more context in your search, you can do this:

cat BIG_FILE.txt | less

Doing a search in less should highlight your search terms.

Or pipe the output to your favorite editor. One example:

cat BIG_FILE.txt | vim -

Then search/highlight/replace.

Solution 9 - Linux

If you are looking for a pattern in a directory recursively, you can either first save it to file.

ls -1R ./ | list-of-files.txt

And then grep that, or pipe it to the grep search

ls -1R | grep --color -rE '[A-Z]|'

This will look of listing all files, but colour the ones with uppercase letters. If you remove the last | you will only see the matches.

I use this to find images named badly with upper case for example, but normal grep does not show the path for each file just once per directory so this way I can see context.

Solution 10 - Linux

Maybe this is an XY problem, and what you are really trying to do is to highlight occurrences of words as they appear in your shell. If so, you may be able to use your terminal emulator for this. For instance, in Konsole, start Find (ctrl+shift+F) and type your word. The word will then be highlighted whenever it occurs in new or existing output until you cancel the function.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMartin KonecnyView Question on Stackoverflow
Solution 1 - LinuxholygeekView Answer on Stackoverflow
Solution 2 - LinuxSorinView Answer on Stackoverflow
Solution 3 - LinuxwillkilView Answer on Stackoverflow
Solution 4 - LinuxkepkinView Answer on Stackoverflow
Solution 5 - LinuxacrosView Answer on Stackoverflow
Solution 6 - LinuxjackhabView Answer on Stackoverflow
Solution 7 - LinuxLeon X. W.View Answer on Stackoverflow
Solution 8 - Linuxdgo.aView Answer on Stackoverflow
Solution 9 - LinuxtristanbaileyView Answer on Stackoverflow
Solution 10 - LinuxRoger DahlView Answer on Stackoverflow