297

I use the --colour option of grep a lot, but I often use less as well. How can I pipe grep results to less and still preserve the coloring. (Or is that possible?)

grep "search-string" -R * --colour | less 

EDIT:

I'm looking for a direct solution or anything equivalent to this.

3
  • possible duplicate of Get colors in 'less'' command Commented Sep 19, 2014 at 8:07
  • What does * do? From the man page of grep: *: The preceding item will be matched zero or more times. But I still don't understand..! @JeremyPowell
    – Shayan
    Commented Sep 1, 2019 at 17:37
  • 1
    @Shayan, the '*' in this case is for the file arguments. It gets processed by the shell which expands it to all files in the directory. The search string is enclosed in double quotes in the example.
    – NeilG
    Commented Nov 2, 2019 at 4:15

5 Answers 5

343

When you simply run grep --color it implies grep --color=auto which detects whether the output is a terminal and if so enables colors. However, when it detects a pipe it disables coloring. The following command:

grep --color=always -R "search string" * | less

Will always enable coloring and override the automatic detection, and you will get the color highlighting in less.

EDIT: Although using just less works for me, perhaps older version require the -R flag to handle colors, as therefromhere suggested.

15
  • 180
    You need to use less -R for the colour encoding to be interpreted by less correctly Commented Sep 4, 2009 at 23:24
  • 1
    It worked for me with just less, it may be version dependent.
    – drrlvn
    Commented Sep 5, 2009 at 12:14
  • 4
    A (hopefully) useful addendum: I needed to exclude some matches but maintain the colouring, so I actually ended up with grep pattern file | grep -v badpattern | grep --colour=always pattern | less -R, which met my needs perfectly. (Thanks again!) Commented Mar 6, 2012 at 15:35
  • 9
    I can't believe they just implemented the color-handling feature in less and therefore missed the chance to have a special colorless tool. For the name alone it should have been done! I should probably write a patch that invokes -R automatically when the binary is run as colorless.
    – Christian
    Commented Jul 10, 2013 at 0:42
  • 2
    @OwenBlacker It might not be an alias. You might have $LESS set with -R.
    – greyfade
    Commented Aug 30, 2016 at 21:01
34

You can put this in your .bashrc file:

export GREP_OPTIONS="--color=always"

or create an alias like this:

alias grepc="grep --color=always"

and you will need to use the -R option for less, as pointed out by therefromhere

3
  • 39
    Warning!: GREP_OPTIONS="--color=always" may break many scripts that use grep (or (e|f)grep).
    – mctylr
    Commented Mar 12, 2010 at 19:25
  • 4
    Yeah, better to just alias grep. You can always get pure grep with GREP, or override the --color option manually.
    – asmeurer
    Commented Jul 18, 2011 at 22:51
  • This doesn't work for me, alias does work though.
    – saeedgnu
    Commented Feb 28, 2014 at 3:30
17

In case like this, I prefer to actually create small sh files and put them on /usr/local/bin.
I usually use grep in the recursive way on the pwd, so thats my personal script:

#!/bin/sh
grep --color=always -r "$@" . | less -R

And then I've just copied it as /usr/local/bin/g (yes, I use it a lot)

2
  • 3
    Why not just use shell functions for this kind of thing? g() { grep --color=always -r "$@" . | less -R } works identically and probably will give (minutely) better performance.
    – 00dani
    Commented Jan 11, 2017 at 2:00
  • 2
    @00dani yeah, that's a valid alternative too and sometimes I use it. Please note that in this case, most time is spent in IO and therefore there is no perceivable performance boost :) Another difference is that once in your PATH, this script can be used with other shell scripts and aliases too; the function instead needs to be explicitly loaded
    – Iazel
    Commented Jan 27, 2019 at 12:15
2

Don't alias "grep", better to alias "less" which is never used by shells. In your .bashrc just put: alias less="less -r".

5
  • 4
    Not quite right. One needs to use both grep --color=always and less -R. Note that grep only knows it is being piped into some other process and the --color=auto option uses solely this information to decide if will output colors or not.
    – brandizzi
    Commented Apr 17, 2013 at 18:35
  • 4
    Note that less option -r is different than -R. Probably -R is safer. Commented Jan 9, 2014 at 0:26
  • 1
    So why down-vote my solution. The OP specifically ask for less with the example already using `--color' option.
    – not2qubit
    Commented Jan 9, 2014 at 15:58
  • 3
    An alias is probably undesirable here. less supports a $LESS environment variable. So, instead of an alias, export LESS='-R' might be preferable.
    – greyfade
    Commented Aug 30, 2016 at 20:59
  • @greyfade "an alias is probably undesirable here" why? envvars are more flexible to be sure, but you can unalias a command if needed. Commented Oct 23, 2022 at 17:12
0

You can run

grep --color=always -R "search string" * | less -r

with the -r flag after less, in order for this to work.

2
  • What does * do? From the man page of grep: *: The preceding item will be matched zero or more times. But I still don't understand..!
    – Shayan
    Commented Sep 1, 2019 at 17:36
  • 2
    @Shayan It will search for the text "search string" in all files.
    – Pepedou
    Commented Jun 1, 2020 at 19:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .