Cat Command – How to Colorize Output Including Unknown Filetypes

catcolorssource-highlight

I like the colors I have in vim. Can I get my output similarly colorized when I do a cat?

I like that I can use the colorize tool as in Colorized `cat` for source and script files?. I would like that to be my standard for cat, e.g. I create an alias:

alias cat="source-highlight --out-format=esc -o STDOUT -i"

However if the file type is unknown, say .gitignore then this will return:

$ cat .gitignore_global
source-highlight: could not find a language definition for input file .gitignore

How could I have the command do a source-highlight cat version if it is a recognized file type and otherwise just do a standard black and white cat of the file?

One option is to have the alias be ccat but I'd prefer to have it replace cat itself if possible.

It would also be nice to be able to use wildcards, e.g. cat *.rb (or even ccat *.rb)? Currently that gives:

$ ccat *.rb
Please, use one of the two syntaxes for invocation: 
source-highlight [OPTIONS]... -i input_file -o output_file
source-highlight [OPTIONS]... [FILES]...

and it would be great to be able to do:

ls *.rb | xargs ccat # (or cat)

the same way I can do:

ls *.rb | xargs cat

Currently I get:

$ ls *.rb | xargs ccat
xargs: ccat: No such file or directory

Best Answer

Perhaps you could do something like the following script (untested):

#!/bin/sh

for fn in "$@"; do
    source-highlight --out-format=esc -o STDOUT -i $fn 2>/dev/null || /bin/cat $fn
done

This does a few things:

  • iterates through each command line argument
  • tries to run source-highlight, redirecting error output to /dev/null
  • if source-highlight fails, then run regular /bin/cat

You put this script in a file named cdc for example, then alias cat=cdc.

As a function

You can adapt the above script into a Bash function call which can then be incorporated into your dot files like so:

cdc() { 
  for fn in "$@"; do 
    source-highlight --out-format=esc -o STDOUT -i $fn 2>/dev/null || /bin/cat $fn;
  done 
}

Edit (Michael) for some reason trying to use ccat for the function name didn't work but cdc did!