Truncate Long Matching Lines of Grep: a Solution That Preserves Color

Last updated on December 10, 2016

It is well known that long matching lines returned by grep is often disturbing. For example, a simple grep on a bootstrap javascript file bootstrap.min.js can cause a crazy tragedy—one single matching line can occupy a number of lines in the terminal:
A tragedy of grep.
How can we solve this issue?

A Popular Working Solution, But …

One popular solution that floating around the Internet suggests using the -o option combined with some regular expression tricks. For the example above, the following command should print only 20 characters before and after the searching keyword (This requires GNU grep. If you are on Mac OS X and using the BSD grep, please consider following this article to install GNU grep):

grep -oE '.{0,20}jQuery.{0,20}' bootstrap.min.js

However, when the grep color output is enabled with the --color=auto option, the output looks like this:
The color output of grep is messed up.
Everything is highlighted but we only want to highlight the matching string jQuery! What can we do now?

The Ultimate Solution That Preserves the Color

To solve this issue, I’ve created the following piece of shell script (Again, this requires GNU grep. If you are on MacOS/OS X and are using the BSD grep, please consider following this article to install GNU grep):


To use this script, simply download it, give it the executable permission, and put it somewhere in your PATH environmental variable. (The script is also available on GitHub Gist.) Let’s give it a try:
Output of grepl.
Looks great, isn’t it? Run grepl --help for more details.

To search a directory, you can use the following command:

find . -type f  -exec grepl -H pattern '{}' \; 

5 thoughts on “Truncate Long Matching Lines of Grep: a Solution That Preserves Color

  1. Diagon

    The “pattern” should actually be identified as the first after the options, rather than the next to last argument. Otherwise, it’s not possible to grep multiples files in a directory. Also, the nice centering of the greped-for string fails when it appears near the beginning of the line in the file. In that case, the searched-for highlighted string appears shifted to the left.

    If I get time to work out how to fix this, I’ll be back.

    Reply
  2. Anders Lönnberg

    Nice script. I like it 🙂 I just quickly added the option to override the content_length to mine.

    # how many characters around the searching keyword should be shown?
    context_length=10
    
    for i in "$@" 
    do
    case $i in
        -C=*|--length=*)
        context_length="${i#*=}"
        shift 
        ;;
    esac
    done
    
    Reply
    1. Hong Xu

      Thanks, I’ve updated the script to incorporate that! I’ve modified the code slightly to allow users only able to specify the context length as the first argument, since your `shift` call won’t work when `i` is not 1 🙂

      Reply

Leave a Reply

Your email address will not be published.