19

When I use e.g. cat file.txt | grep --color=tty "pattern" I get the pattern I search highlighted. When I want some more context around each hit, grep has the -A, -B and -C parameters.

However, I want to display the whole file (or whatever command output) and highlight a certain pattern. Does such a highlight command or tool exist?

1
  • How is what you want to do now different from what you already do? Oct 13 '10 at 17:01
22

There was an answer on unix.stackexchange.com that had this neat trick:

grep -E --color 'pattern|$' file.txt

or

grep --color 'pattern\|$' file.txt

which matches your pattern or the end-of-line on each line. Only the pattern is highlighted.

3
  • +1 Simple, and easily adaptable to zgrep, bzgrep, etc. Nice! Oct 14 '10 at 3:47
  • Is there any way to avoid typing --color all the time? I think its pretty basic to embed color option into grep, not sure why we have explicitly type in color every single time. I tried to create scripts say grepd files has a bash saying grep --color $1 $2 but it doesnt work. Any clue here to fix this please May 2 '13 at 17:47
  • 1
    @lordlupine: Add GREP_OPTIONS='--color' to your ~/.bashrc (or modify the setting to include --color). You will need to start a new terminal or execute that assignment at the command line in the current terminal to have it take effect. May 2 '13 at 18:20
10

I like ack.

ack --passthru somepattern filename

It's like grep, but better. It highlights by default, and with the --passthru option it shows the entire file (or standard input) instead of only the matching lines.

3
  • 2
    If you're trying to pipe output into ack, e.g. from tail, then you need to use the --filter option too. For example: tail -f myLogFile | ack --filter --passthru pattern
    – sparrowt
    Nov 28 '13 at 13:58
  • @sparrowt Can you please explain briefly why it's necessary? (e.g. any fringe cases where not using --filter would cause a problem?) I used it w/o --filter and it worked fine.
    – cyqsimon
    Jan 6 at 2:00
  • 1
    I'm afraid my memory from 7 years ago is patchy! At the time I found that (in my environment: OS, shell, version of tail/ack, etc.) --filter was required to "Force ack to treat standard input as a pipe" per the ack documentation. I'm not sure why it was necessary, or whether something has been fixed since then - so if it works without that's great, but if someone finds it doesn't work then try adding --filter! :)
    – sparrowt
    Jan 6 at 11:52
6

I also recommend the use of less (or such), but I want to show you a more didactical solution. Once you have defined this function:

function highlight()
{
    sed "s/$1/`tput smso`&`tput rmso`/g" "${2:--}"
}

You can use it this way:

command | highlight pattern
highlight pattern file.txt

Note: This version is case sensitive, to change that just append i after g in the sed expression.

5
  • 1
    I'd invoke tput instead of hardcoding the values. This way you also avoid using echo -e, which can have other effects. Oct 13 '10 at 18:25
  • You're absolutely right, I searched it with no luck. Thanks.
    – cYrus
    Oct 13 '10 at 18:37
  • This version doesn't need the capturing parentheses and can be run either by prog | highlight "pattern" or highlight "pattern" file: highlight () { local file=${2:--}; sed "s/$1/$(tput smso)&$(tput rmso)/gi" "$file"; } Oct 14 '10 at 4:45
  • My sed skills are basically not existent. How would I have to change that in order to match the pattern case sensitive. Anyway, I will add that one to my bash_functions include. Thank you very much.
    – DerMike
    Oct 14 '10 at 7:31
  • @DerMike: Now it's case sensitive.
    – cYrus
    Oct 14 '10 at 12:46
3

Passing -C to grep with a sufficiently high value will do this.

2
  • I Could have sworn I got some thing else last time I tried that. (Each match the context with '-----' separators in between.) Now that you told me, it runs fine :-) Thank you.
    – DerMike
    Oct 14 '10 at 7:22
  • It will separate each match, if there isn't enough context. Oct 14 '10 at 7:23
3

less is highlighting pattern, so

less -p 'mypattern' file.txt

or

ridiculously | long | pipe | less

and then in less / to search for a pattern which will be highlighted.

Side note:

You can improve your command, for example
set alias alias grep="grep --color=tty" and use it like that:

grep 'mypattern' file.txt;
3
  • 1
    you should refrain from using GREP_OPTIONS, use alias instead. see: bugs.launchpad.net/ubuntu/+bug/67141
    – lesmana
    Oct 13 '10 at 18:29
  • Primum non nocere. removed. Oct 13 '10 at 18:43
  • GREP_OPTIONS is used by many forms of grep (zgrep, bzgrep, bzfgrep, etc.) So, if you want all forms of grep to behave consistently, you'd need to set an alias for each form of grep. @Casual's new answer above won't for with something like bzgrep pattern /var/log/messages.?.gz, which is an example where color highlighting be VERY helpful. Oct 14 '10 at 3:24
1

There's a nice supercat tool, which serves exactly that purpose. It can both colorize your console output and produce a "highlighted" html from your input.

3
  • Thanks, that looks promissing. However, I can't seem to get it working at the moment.
    – DerMike
    Oct 6 '11 at 9:16
  • 1
    Take a look at its config files (in /etc/supercat on Ubuntu), which set up the coloring rules, they are basically color/regexp pairs (with some extra rules); man page is also short and nice. Oct 6 '11 at 17:29
  • I found a spcrc vim syntax file at vim.org/scripts/script.php?script_id=2676
    – DerMike
    Oct 7 '11 at 8:39

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.