When I read a file in Linux with the command less or more, how can I get the content in colors?
17 Answers
If you just want to tell less to interpret color codes, use less -R. ref.
You can utilize the power of pygmentize with less - automatically! (No need to pipe by hand.)
Install pygments with your package manager or pip (possibly called python-pygments) or get it here .
Write a file ~/.lessfilter
#!/bin/sh
case "$1" in *.awk|*.groff|*.java|*.js|*.m4|*.php|*.pl|*.pm|*.pod|*.sh|\ *.ad[asb]|*.asm|*.inc|*.[ch]|*.[ch]pp|*.[ch]xx|*.cc|*.hh|\ *.lsp|*.l|*.pas|*.p|*.xml|*.xps|*.xsl|*.axp|*.ppd|*.pov|\ *.diff|*.patch|*.py|*.rb|*.sql|*.ebuild|*.eclass) pygmentize -f 256 "$1";; .bashrc|.bash_aliases|.bash_environment) pygmentize -f 256 -l sh "$1";; *) if grep -q "#\!/bin/bash" "$1" 2> /dev/null; then pygmentize -f 256 -l sh "$1" else exit 1 fi
esac
exit 0In your .bashrc (or .zshrc or equivalent) add
export LESS='-R'
export LESSOPEN='|~/.lessfilter %s'Also, you need to make ~/.lessfilter executable by running
chmod u+x ~/.lessfilterEdit: If you have lesspipe on your system, you might want to use that to automatically unzip archives when looking at them with less, e.g. less log.gz. lesspipe also supports a custom .lessfilter file, so everything said above works the same, you just have to run
eval "$(lesspipe)" in your rc file instead of setting the LESSOPEN variable. Run echo "$(lesspipe)" to see what it does. Your .lessfilter will still work. See man lesspipe.
Tested on Debian.
You get the idea. This can of course be improved further, accepting more extensions, multiple files, or parsing the shebang for other interpreters than bash. See some of the other answers for that.
The idea came from an old blog post from the makers of Pygments, but the original post doesn't exist anymore.
Btw. you can also use this technique to show directory listings with less.
Try the following:
less -Rfrom man less:
13
-ror--raw-control-charsCauses "raw" control characters to be displayed. (...)
-Ror--RAW-CONTROL-CHARSLike
-r, but only ANSI "color" escape sequences are output in "raw" form. (...)
I got the answer in another post: Less and Grep: Getting colored results when using a pipe from grep to less
When you simply run
grep --colorit impliesgrep --color=autowhich 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 "search string" * | less -RWill always enable coloring and override the automatic detection, and you will get the color highlighting in less.
Warning: Don't put --color=always as an alias, it break things sometimes. That's why there is an --color=auto option.
Use view instead of less. It opens the file with vim in readonly mode.
It's practically a coloured less: a pager where you can search with / (and more). The only drawback is that you can't exit with q but you need :q
Also, you get the same colouring as vim (since you're in fact using vim).
To tell less to show colors call it with -R:
less -RUnfortunately some programs detect that their stdout is not a terminal and disable colors - e.g pacman (Arch Linux package manager).
In those cases its possible to use unbuffer:
unbuffer <command> | less -RExample using pacman
unbuffer pacman -Ss firefox | less -RThe unbuffer command is usually part of the package expect (Arch Linux, Debian/Ubuntu) or expect-dev (legacy versions of Debian/Ubuntu).
To answer the question for completeness:
As others already answered, pygmentize is great for colorizing source code. It does not require unbuffer. Easiest call:
pygmentize someSource.cpp | less -R 5 pygmentize supports the -g option to automatically guess the lexer to be used which is useful for files read from STDIN without checking any extension type.
Using that, you only need to set the following 2 exports in your .bashrc without any additional scripts:
export LESS='-R'
export LESSOPEN='|pygmentize -g %s' 1 You didn't say what this color should mean, e.g. what should the colors be for a text file?
If what you want is syntax highlighting for source code, you need a source code highlighter. I sometimes use pygmentize like this
pygmentize file.cpp | lessor
pygmentize file.cpp | moreThere are other highlighters around.
This is pretty fast. If you don't mind firing up vim there is a read-only mode that can give you syntax highlighting if you have it in vim.
view file.cppor alternatively see churnd's answer.
This is yet another pygments-based answer, with several major improvements:
- does not break
lesspipeorlessfilefilters - works with multiple inputs to
less - correctly parses the script type from the shebang header
- works for all 434 file types lexable by Pygments
- color scheme is parameterized as an environment variable
EDIT: I maintain an updated/improved version of this script here:
Original version below:
Install Pygments and Gawk
sudo apt-get install python-pygments python3-pygments gawkSet Environment Variables
Check whether lesspipe or lessfile is already enabled:
echo $LESSOPENIf you don't see either program referenced there, ensure that lesspipe is installed (most distros come with it).
Add the following to ~/.bashrc:
# sets LESSOPEN and LESSCLOSE variables
eval "$(SHELL=/bin/sh lesspipe)"
# interpret color characters
export LESS='-R'
# to list available styles: `pygmentize -L styles`
export PYGMENTIZE_STYLE='paraiso-dark'
# optional
alias ls='ls --color=always'
alias grep='grep --color=always'If you don't want lesspipe, replace the eval statement with:
export LESSOPEN='|~/.lessfilter %s'Create ~/.lessfilter
Add the following code and make the file executable: chmod u+x ~/.lessfilter
#!/bin/bash
for path in "$@"; do # match by known filenames filename=$(basename "$path") case "$filename" in .bashrc|bash.bashrc|.bash_aliases|.bash_environment|.bash_profile|\ .bash_login|.bash_logout|.profile|.zshrc|.zprofile|.zshrc|.zlogin|\ .zlogout|zshrc|zprofile|zshrc|zlogin|zlogout|.cshrc|.cshdirs|\ csh.cshrc|csh.login|csh.logout|.tcshrc|.kshrc|ksh.kshrc) # shell lexer pygmentize -f 256 -O style=$PYGMENTIZE_STYLE -l sh "$path" ;; .htaccess|apache.conf|apache2.conf|Dockerfile|Kconfig|external.in*|\ standard-modules.in|nginx.conf|pacman.conf|squid.conf|termcap|\ termcap.src|terminfo|terminfo.src|control|sources.list|CMakeLists.txt|\ Makefile|makefile|Makefile.*|GNUmakefile|SConstruct|SConscript|\ .Rhistory|.Rprofile|.Renviron|Rakefile|Gemfile|PKGBUILD|autohandler|\ dhandler|autodelegate|.vimrc|.exrc|.gvimrc|vimrc|exrc|gvimrc|todo.txt) # filename recognized pygmentize -f 256 -O style=$PYGMENTIZE_STYLE "$path" ;; *) ext=$([[ "$filename" = *.* ]] && echo ".${filename##*.}" || echo '') case "$ext" in .as|.mxml|.bc|.g|.gd|.gi|.gap|.nb|.cdf|.nbp|.ma|.mu|.at|.run|\ .apl|.adl|.adls|.adlf|.adlx|.cadl|.odin|.c-objdump|.s|\ .cpp-objdump|.c++-objdump|.cxx-objdump|.d-objdump|.S|.hsail|\ .ll|.asm|.ASM|.objdump-intel|.objdump|.tasm|.au3|.ahk|.ahkl|\ .bb|.decls|.bmx|.bas|.monkey|.BAS|.bst|.bib|.abap|.ABAP|.cbl|\ .CBL|.cob|.COB|.cpy|.CPY|.gdc|.maql|.p|.cls|.c|.h|.idc|.cpp|\ .hpp|.c++|.h++|.cc|.hh|.cxx|.hxx|.C|.H|.cp|.CPP|.ino|.clay|\ .cu|.cuh|.ec|.eh|.mq4|.mq5|.mqh|.nc|.pike|.pmod|.swg|.i|.vala|\ .vapi|.capnp|.chpl|.icl|.dcl|.cf|.docker|.ini|.cfg|.inf|\ .pc|.properties|.reg|.tf|.pypylog|.cr|.csd|.orc|.sco|.css|\ .less|.sass|.scss|.croc|.d|.di|.smali|.jsonld|.json|.yaml|\ .yml|.dpatch|.darcspatch|.diff|.patch|.wdiff|.boo|.aspx|.asax|\ .ascx|.ashx|.asmx|.axd|.cs|.fs|.fsi|.n|.vb|.als|.bro|.crmsh|\ .pcmk|.msc|.pan|.proto|.pp|.rsl|.sbl|.thrift|.rpf|\ .dylan-console|.dylan|.dyl|.intr|.lid|.hdp|.ecl|.e|.elm|.ex|\ .exs|.erl|.hrl|.es|.escript|.erl-sh|.aheui|.befunge|.bf|.b|\ .camkes|.idl4|.cdl|.cw|.factor|.fan|.flx|.flxh|.frt|.f|.F|\ .f03|.f90|.F03|.F90|.PRG|.prg|.go|.abnf|.bnf|.jsgf|.cyp|\ .cypher|.asy|.vert|.frag|.geo|.plot|.plt|.ps|.eps|.pov|.inc|\ .agda|.cry|.hs|.idr|.kk|.kki|.lagda|.lcry|.lhs|.lidr|.hx|\ .hxsl|.hxml|.sv|.svh|.v|.vhdl|.vhd|.dtd|.haml|.html|.htm|\ .xhtml|.xslt|.pug|.jade|.scaml|.xml|.xsl|.rss|.xsd|.wsdl|\ .wsf|.xpl|.pro|.ipf|.nsi|.nsh|.spec|.i6t|.ni|.i7x|.t|.io|\ .ijs|.coffee|.dart|.eg|.js|.jsm|.juttle|.kal|.lasso|\ .lasso[89]|.ls|.mask|.j|.ts|.tsx|.jl|.aj|.ceylon|.clj|\ .cljs|.golo|.gs|.gsx|.gsp|.vark|.gst|.groovy|.gradle|.ik|\ .java|.kt|.pig|.scala|.xtend|.cpsa|.cl|.lisp|.el|.hy|.lsp|.nl|\ .kif|.rkt|.rktd|.rktl|.scm|.ss|.shen|.xtm|.cmake|.mak|.mk|\ .[1234567]|.man|.md|.css.in|.js.in|.xul.in|.rst|.rest|.tex|\ .aux|.toc|.m|.sci|.sce|.tst|.ml|.mli|.mll|.mly|.opa|.sml|.sig|\ .fun|.bug|.jag|.mo|.stan|.def|.mod|.mt|.ncl|.nim|.nimrod|.nit|\ .nix|.cps|.x|.xi|.xm|.xmi|.mm|.swift|.ooc|.psi|.psl|.G|.ebnf|\ .rl|.treetop|.tt|.adb|.ads|.ada|.pas|.dpr|.pwn|.sp|.pl|.pm|\ .nqp|.p6|.6pl|.p6l|.pl6|.6pm|.p6m|.pm6|.php|.php[345]|.zep|\ .praat|.proc|.psc|.lgt|.logtalk|.prolog|.pyx|.pxd|.pxi|.dg|\ .py3tb|.py|.pyw|.sc|.tac|.sage|.pytb|.qvto|.Rout|.Rd|.R|.rq|\ .sparql|.ttl|.r|.r3|.reb|.red|.reds|.txt|.rnc|.graph|\ .instances|.robot|.fy|.fancypack|.rb|.rbw|.rake|.gemspec|\ .rbx|.duby|.rs|.rs.in|.SAS|.sas|.applescript|.chai|.ezt|\ .mac|.hyb|.jcl|.lsl|.lua|.wlua|.moo|.moon|.rexx|.rex|.rx|\ .arexx|.sh|.ksh|.bash|.ebuild|.eclass|.exheres-0|.exlib|.zsh|\ .sh-session|.shell-session|.bat|.cmd|.fish|.load|.ps1|.psm1|\ .tcsh|.csh|.ns2|.st|.smv|.snobol|.rql|.sql|.sqlite3-console|\ .do|.ado|.scd|.tcl|.rvt|.ng2|.tmpl|.spt|.cfc|.cfm|.cfml|\ .evoque|.kid|.handlebars|.hbs|.phtml|.jsp|.liquid|.mao|.mhtml|\ .mc|.mi|.myt|.rhtml|.tpl|.ssp|.tea|.twig|.vm|.fhtml|.sls|\ .feature|.tap|.awk|.vim|.pot|.po|.weechatlog|.todotxt|.thy|\ .lean|.rts|.u|.vcl|.bpl|.sil|.vpr|.cirru|.duel|.jbst|.qml|\ .qbs|.slim|.xqy|.xquery|.xq|.xql|.xqm|.whiley|.x10) # extension recognized pygmentize -f 256 -O style=$PYGMENTIZE_STYLE "$path" ;; *) # parse the shebang script header if it exists lexer=$(head -n 1 "$path" |grep "^#\!" |awk -F" " \
'match($1, /\/(\w*)$/, a) {if (a[1]!="env") {print a[1]} else {print $2}}') case "$lexer" in node|nodejs) # workaround for lack of Node.js lexer alias pygmentize -f 256 -O style=$PYGMENTIZE_STYLE \ -l js "$path" ;; "") exit 1 ;; *) pygmentize -f 256 -O style=$PYGMENTIZE_STYLE \ -l $lexer "$path" ;; esac ;; esac ;; esac
done
exit 0 1 Use the GNU Source-highlight; you can install it with apt if you have it, or otherwise install it from source. Then set up an "input preprocessor" for less, with help from the Source-highligh' documentations for setting up with less:
This was suggested by Konstantine Serebriany. The script src-hilite-lesspipe.sh will be installed together with source-highlight. You can use the following environment variables:
export LESSOPEN="| /path/to/src-hilite-lesspipe.sh %s" export LESS=' -R 'This way, when you use less to browse a file, if it is a source file handled by source-highlight, it will be automatically highlighted.
Xavier-Emmanuel Vincent recently provided an alternative version of ANSI color scheme, esc256.style: some terminals can handle 256 colors. Xavier also provided a script which checks how many colors your terminal can handle, and in case, uses the 256 variant. The script is called source-highlight-esc.sh and it will be installed together with the other binaries.
Condensed from my full blog post about improving less experience:
For colorful manpages, add the following to your .bashrc or .zshrc:
export LESS_TERMCAP_mb=$'\E[1;31m' # begin bold
export LESS_TERMCAP_md=$'\E[1;36m' # begin blink
export LESS_TERMCAP_me=$'\E[0m' # reset bold/blink
export LESS_TERMCAP_so=$'\E[01;44;33m' # begin reverse video
export LESS_TERMCAP_se=$'\E[0m' # reset reverse video
export LESS_TERMCAP_us=$'\E[1;32m' # begin underline
export LESS_TERMCAP_ue=$'\E[0m' # reset underlineFor syntax highlighting, using an existing powerful lesspipe.sh to handle it instead of writing your own:
To expand upon another answer, you can make it work for most if not all of your scripts that don't have extensions by changing the .lessfilter file around just a bit:
#!/bin/sh case "$1" in *.awk|*.groff|*.java|*.js|*.m4|*.php|*.pl|*.pm|*.pod|*.sh|\ *.ad[asb]|*.asm|*.inc|*.[ch]|*.[ch]pp|*.[ch]xx|*.cc|*.hh|\ *.lsp|*.l|*.pas|*.p|*.xml|*.xps|*.xsl|*.axp|*.ppd|*.pov|\ *.diff|*.patch|*.py|*.rb|*.sql|*.ebuild|*.eclass) pygmentize -f 256 "$1";; .bashrc|.bash_aliases|.bash_environment) pygmentize -f 256 -l sh "$1" ;; *) scriptExec=$(head -1 "$1" |grep "^#\!" |awk -F" " '{print $1}') scriptExecStatus=$? if [ "$scriptExecStatus" -eq "0" ]; then lexer=$(echo $scriptExec |awk -F/ '{print $NF}') pygmentize -f 256 -l $lexer "$1" else exit 1 fi
esac
exit 0You'd still need to add the two variables to .bashrc:
export LESS='-R'
export LESSOPEN='|~/.lessfilter %s'And you'll still need to make .lessfilter executable:
$ chmod 700 ~/.lessfilterAlso I wanted to add that under debian the pygments package is called python-pygments. I had trouble locating it at first because the obvious misspelling of "pigments" as "pygments" wasn't enough of a hint to me that it was a package that might be prefixed with "python-" by the package manager.
1An alternative to less/more that works with colors out of the box is bat. You can install it with most package managers use it as a pager as well as a cat replacement.
1You can consider using most utility which is colour-friendly alternative for less and more.
I found this simple elegant solution. You don't have to install anything extra as it is already there by default on most machines. As vim is installed by default on most machines, it includes a macro to run vim like less
Some of the options to use it are to create an alias:alias vless='vim -u /usr/share/vim/vim74/macros/less.vim'
or create a symbolic link:ln -s /usr/share/vim/vim74/macros/less.sh ~/bin/vless
Then you just run vless myfile.py
I got most of the information here
1The most intuitive and straight forward solution for me was using pygmentize
by adding the lines below to .bashrc
export LESS='-R'
export LESSOPEN='|pygmentize -g %s'In case you couldn't call pygmentize, just install like
pip install pygmentsps. The pygmentize executable binary would sit in /usr/local/bin/ or in your /home/username/.virtualenv/venvname/bin/ or somewhere.
As long as the output text have color control characters, less -R will do.
None of these were working out of the box for me and I figured out an easy way to make this work so I thought I would share.
Just use tmux, that allows you access and scroll through a larger history and preserves the colors perfectly.
2