14

Is there a command which can be used to easily highlight (with colors, bold text or inverted back-/foreground) specific strings in stdin while passing the entire string to stdout? I'm thinking of building it, but I'd rather just use it if it already exists. Some desirable features:

  1. Separate highlight strings are highlighted differently, in an automatic way. For example, the first string will be highlighted in red, the second in green, the third in blue without manual configuration.
  2. Detects color support and falls back to bold/inverted/other highlighting methods where those are available.
  3. Allow for matching of regular expressions and literal strings.
  4. Preferably does something smart if the matches overlap, such as "foobar" and "barbar".
  5. Nothing is modified between stdin and stdout except for the addition of color codes.
l0b0
  • 51,350

7 Answers7

6

Sed to the rescue!

You can improve this (as it really need it) but it works pretty well.

$ cat >~/bin/hilight <<EOF
#!/bin/bash
while [ $# -gt 0 ]
do
 COMANDO=$COMANDO's/'$1$'/\033[01;'$2$'m\033[K\\0\033[m\033[K/g\n'
 shift;shift;
done

sed -e "$COMANDO"
EOF

For sake of simplicity, hilight accepts pair of arguments (first the match, second the color) In this script the attrib is always bold

Read man console_codes (Graphic Rendition) to see color escape secuences, or try this

for attrib in $(seq 0 12); do
  for color in $(seq 30 37) $(seq 40 47) $(seq 90 97); do
    printf %b " $attrib $color:\033[$attrib;${color}mhi, dudes\033[m"
  done
done

It has important drawbacks as using this works:

$ dmesg | hilight \\[ 34 ] 34

but this not at all:

$ dmesg | hilight \\[ 34 ] 34 [[:digit:]] 31

because [:digit:] finds the numbers in the escape secuences on previous sustitutions.

Something like:

$ cat /var/log/kern.log | hilight kernel 31 a 34 et 33

will always work as excepted.

Using time command I found this increments by four the time elapsed, which is not too much.

You can replace sed command with any other parser you like or fits your needs (awk, etc...)

4

One can also use egrep with pattern that matches every line on non-printable character, like:

dmesg | egrep --color "swap|$"
4

Maybe Radovan Garabík's Generic Colouriser (grc)? It expects a config file as argument and works with regexp's. So not quite without configuration, but you can use process process substitution (<(list)), so by all means without manual configuration :-)

wnrph
  • 1,444
  • To clarify without needing to open the page (and to make it searchable), "this one" == Generic Colouriser; grc and grcat ... Thanks, I like it. – Peter.O Jul 27 '11 at 11:33
  • grc has a helper script: grcat. Here is an example of colouring all capital letters in red. Step 1: Set up the config file: printf "regexp=[A-Z]\ncolours=red\n" > ~/.grc/red-caps Step 2; Use it: echo Hello World | grcat red-caps ... The man page states 3 config directories it searches, and then suggests(?) that the config file can be an absolute path, but this last method of finding the config file only works with relative paths for me (grc version 1.3) – Peter.O Nov 01 '11 at 01:49
2

If your version of grep comes with coloration, then you can use regexp alteration to make grep highlight the text and also match every line so that nothing is excluded. The following should do the trick:

<your command> |grep "highlightme\|^"
EoghanM
  • 887
1

clide works fine. I use it on RHEL 6.2, from the EPEL repository

golimar
  • 417
0

I use http://em.readthedocs.org/. Easy to install on various platforms because of Python. Simple and works fine.

  • Welcome to Unix & Linux Stack Exchange! Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. – slm Jan 22 '14 at 15:02
  • 2
    According to [help/behavior]: “However, you must disclose your affiliation in your answers.” In case you are the same Igor Kalnitsky who wrote em, please reword your answer to be clear that you are not a user, but the author of the suggested tool. – manatwork Jan 22 '14 at 15:18
0

While imperfect and unrefined, for simple highlights in bash strings, the grep command then grep again, ie grep piped to grep, can make quick work of simple highlight with the -B before and/or -A after options. Easier than sed command or others for simple jobs.

man journalctl | grep  EXAMPLE -A100 | grep -A20 highlightword1

grep DOCFOCUSWORDSECTIONETC -B20 -A100 filename.txt | grep -P highlightword1 -B20 -A20

Use >> file.txt or >> tee for cleanup edits .

Use smaller or larger, - B Before and/or -A After line number options to narrow or expand ranges of text as required, ie -B1000 -A1000 for a full document. Bonus - overlaps are not repeated. Limits - single color highlight.

Aside, a quick note for grep newbies, try:

grep -i "word1\|word2\|word3" fname.md
grep -Pi "word1|word2|word3" fname.md
grep -Pi "^.*word1|word2.*next|word2.*$"  fname

Use -i for CAPS/not and -P for simple | for OR. Don't confuse the | for OR with | for PIPE to. ^ for line start and $ for line end in -P regex.

Aside, maybe more apt solution to question here is the app batcat (apt install batcat) that has good set of default --language options and new custom syntax/languages can be added.

FargolK
  • 1,667
Cymatical
  • 101