This question already has answers here:
How to change the output color of echo in Linux
(33 answers)
How do I output coloured text to a Linux terminal?
(16 answers)
Closed 1 year ago.
For example, I'd like to color the output of the locate command so it's easily distinguished from the other terminal text.
It should work something like this:
locate -bir pdf | some_command_to_color_the_result
Coloring shouldn't be limited for the locate command only: I need a generic solution that colors text using pipelines, for example feeding it the output of grep or cat.
If there's no built-in Linux command, any hints on how to create one are appreciated.
You can use escape sequences to change the font color of any output to the bash shell. Here are some of the color codes you'll need:
BLACK="\033[30m"
RED="\033[31m"
GREEN="\033[32m"
YELLOW="\033[33m"
BLUE="\033[34m"
PINK="\033[35m"
CYAN="\033[36m"
WHITE="\033[37m"
NORMAL="\033[0;39m"
Once these are defined, you can use them in normal echo commands. For instance:
echo -e $GREEN this text is green $NORMAL and this is normal
Note that the -e is not always necessary, but on some OSs (incl. osx) is required for to enable escape sequences.
Given these definitions you can build scripts and pipes to color the output from other commands. Here is a complete example I use to color the output from svn up:
#!/bin/bash
BLACK="\033[30m"
RED="\033[31m"
GREEN="\033[32m"
YELLOW="\033[33m"
BLUE="\033[34m"
PINK="\033[35m"
CYAN="\033[36m"
WHITE="\033[37m"
NORMAL="\033[0;39m"
TMPFILE=.cvsup.tmp
svn up > $TMPFILE
svn status >> $TMPFILE
printf $YELLOW
grep -e ^"\? " -e ^"I " $TMPFILE
printf $GREEN
grep -e ^"R " -e ^"U " -e ^"G " $TMPFILE
printf $BLUE
grep -e ^"M " -e ^"E " $TMPFILE
printf $RED
grep -e ^"C " -e ^"! " -e ^"X " -e ^"~ " $TMPFILE
printf $PINK
grep ^"R " $TMPFILE
printf $PINK
grep ^"D " $TMPFILE
printf $CYAN
grep ^"A " $TMPFILE
printf $NORMAL
rm $TMPFILE
You can also look at tput.
_Esc_="$( printf '\033' )"
_norm_="${Esc}[0m" #returns to "normal"
_bold_="${Esc}[0;1m" #set bold
_red_="${Esc}[0;31m" #set red
_boldred_="${Esc}[0;1;31m" #set bold, and set red.
somecommand | sed -e "s/someregexp/${_boldred_}&${_norm_}/g" # will color any occurence of someregexp in Bold red
printf "%s" "$_red_" ; locate something ; printf "%s" "$_norm_" # will color output of locate something in red
#I (ab)use printf "%s" "something", as it's more portable than echo,and easy to modify
There are many other ways (create a function/script that can colorize a regexp, for example, and then : somecommand | colorize -c _green_ 'foo.*bar' 'other' )
The main tool for that is of course lolcat!
locate -bir pdf | lolcat
To install:
sudo apt install lolcat
See man lolcat for customizations.
As suggested by Jonathan Leffler, comment posted as an anwser:
grep --color will provide colour
The following answered my question:
1- I create an alias in my .bashrc
alias color='grep --color .'
2- Then whenever I want to color the pipeline text output I use color alias like:
locate -bir pdf | color
This will color the output to red
I prefer use highlight utility:
highlight -O xterm256 -S sh
-S sh here means treats the input as shell script syntax.
More info: http://www.andre-simon.de/
I set it as an alias through ~/.bashrc:
There is a far better way to achieve customizable coloring:
colorit
You can use it as shown in other answers via some_command | colorit but it is nicely configurable over the .coloritrc. In mine I have stuff like
dnl Define some useful color variables
define(`red', `1')
define(`green', `2')
define(`magenta', `5')
dnl
dnl Mark macro arguments: regexp foreground-color [background-color]
dnl
define(`mark', ``mark "$1"'' `ifelse(`$#', `3', ``"\033[3$2;4$3m"'',
``"\033[3$2m"'')' `"\033[m"')
dnl
divert
mark(`warning', magenta)
mark(`Warning', magenta)
mark(`Traceback', magenta)
mark(`Error', red)
mark(`FAIL', red)
mark(`ERROR', red)
mark(`XFAIL', green)
mark(`ok', green)
mark(`OK', green)
mark(`PASS', green)
and use it all the time for coloring compiler output and similar stuff. See my .coloritrc for more.
I think the hl command available on git hub might help you :
have a look at http://www.flashnux.com/notes/page_000022_US.html
You should have a look at the hl command available on git hub:
git clone http://github.com/mbornet-hl/hl
and on :
http://www.flashnux.com/notes/page_000022_US.html
hl is a Linux command written in C, especially designed to color a text file or the output of a command. You can use up to 42 colors simultaneously, and use a configuration file to simplify command lines. You can colorize the output of every command that can be piped to another one. And if you know what regular expressions are, it will be very easy for you to use. You can use the man page to understand how to use it.
Use the tput command.
Most terminals support 8 foreground text colors and 8 background colors (though some support as many as 256). Using the setaf and setab capabilities, we can set the foreground and background colors. The exact rendering of colors is a little hard to predict. Many desktop managers impose "system colors" on terminal windows, thereby modifying foreground and background colors from the standard. Despite this, here are what the colors should be:
Value Color
0 Black
1 Red
2 Green
3 Yellow
4 Blue
5 Magenta
6 Cyan
7 White
8 Not used
9 Reset to default color
Actual example: set color to red, cat and then change color back:
tput setaf 1; cat /proc/meminfo ; tput setaf 9
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 1 year ago.
Improve this question
I use default Linux Mint .bashrc, here is full bashrc, the output is like:
some dir has green background, How to remove it?
Quick solution:
Enter these two commands in the Bash command line:
dircolors -p | sed 's/;42/;01/' > ~/.dircolors
source ~/.bashrc
Explanation:
There is a program dircolors intended to set up the config for ls.
The default ~/.bashrc script loads the config with these lines:
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
Because by default the file ~/.dircolors does not actually exist the script uses the built-in Bash config (eval "$(dircolors -b)").
To remove green background for o+w ('writable by others' permission marked by last 'w' in drwxrwxrwx notation in ls) directories you need to create this file basing on the current (built-in) config. In the command line type the following:
dircolors -p > ~/.dircolors
dircolor -p prints the current config and > redirects the output to the given file.
Now open the file in an editor and find the following line:
OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky
change the number 42 (denoting green background) to 01 (no background) and save changes. Alternatively you can do it with sed program and its substitution feature ('s/PATTERN/NEW_STRING/' syntax) from the command line directly:
sed -i 's/;42/;01/' ~/.dircolors
Above 2 things can be achieved by a single command using a pipe '|':
dircolors -p | sed 's/;42/;01/' > ~/.dircolors
To get the change to take the effect (without restarting the shell), type:
source ~/.bashrc
To remove all background colors, stick the following into your ~/.bashrc :
eval "$(dircolors -p | \
sed 's/ 4[0-9];/ 01;/; s/;4[0-9];/;01;/g; s/;4[0-9] /;01 /' | \
dircolors /dev/stdin)"
LS_COLORS is the variable that's referred by ls for colouring its output. If LS_COLORS isn't set, it's generated using dircolors behind the scenes. This can be set manually too with/out using dircolors (see Vivid below).
If most defaults work and you want only a few to be fixed, the easiest is to just set them in your .bashrc.
LS_COLORS=$LS_COLORS:'tw=00;33:ow=01;33:'; export LS_COLORS
This replaces the background colour (42) with normal(00) and bold (01) for
Others-writable directories with sticky bit set (tw)
Others-writable directories without sticky bit (ow)
This is the simplest solution since we keep the defaults for the rest.
The other answer's technique
# -b: make dircolors generate for bash
# sed replaces offending background colors
# sed's output is fed as input for another instance of dircolors
# the entire subshell returns LS_COLORS that's `eval`uated
eval $(dircolors -b | sed 's/ 4[0-9];/ 01;/; s/;4[0-9];/;01;/g; s/;4[0-9] /;01 /' | dircolors /dev/stdin)
simply does this on the fly by getting all the colour values and replacing anything with a background (4[0-9]) with bold (01).
There're better alternatives avoiding all manual fiddling:
LS_COLORS (the project; not to be confused with $LS_COLORS, the variable)
Curated set of colours for different file formats/extensions
Download latest version, evaluate and append to .bashrc
wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O $HOME/.config/LS_COLORS
echo 'eval $(dircolors -b "$HOME/.config/dircolors")' >> $HOME/.bashrc
Vivid
Multiple themes
Generates LS_COLORS on-the-fly
Set $LS_COLORS in .bashrc using vivid command that generates necessary colour codes based on theme
export LS_COLORS="$(vivid generate molokai)"
Both these tool colour schemes don't have background colour for directories of any kind.
The explanation is given in the output of dircolors -p, e.g.,
Of course dircolors doesn't color its output. I used this script:
#!/usr/bin/perl -w
use strict;
our $comment = "\e[31m";
our $reset = "\e[K\e[m";
our #data;
open my $fh, "dircolors -p|" or die "cannot read from dircolors";
#data = <$fh>;
close $fh;
printf "\e[H\e[2J";
for my $n ( 0 .. $#data ) {
chomp $data[$n];
if ( $data[$n] =~ /^\s*#/ ) {
printf "%s%s%s\n", $comment, $data[$n], $reset;
}
elsif ( $data[$n] =~ /^\s*TERM\s/ ) {
printf "%s\n", $data[$n];
}
elsif ( $data[$n] =~ /^\s*[^\s]+\s+\d+(;\d+)?\s*(#.*)?$/ ) {
my $code = $data[$n];
$code =~ s/^\s*[^\s]+\s+//;
$code =~ s/\s.*//;
my $data = $data[$n];
$data =~ s/(#.*)$/$comment$1$reset/;
$data =~ s/^(\s*)([^\s]+)(\s+)/$1\e[${code}m$2\e[m$3/;
printf "%s\n", $data;
}
else {
printf "%s\n", $data[$n];
}
}
1;
To get rid of the background, you can either change the directory permissions, or use a different database to set your LS_COLORS environment variable. The dircolors documentation is the place to go.
I have to filter a very verbose log output that the only pattern between messages for warning or errors is the output text color
Is there a way to filter by the output color when using grep?
When I try to use the color code I have an error due to the [
$ echo -e "Default \e[94mLight blue" | grep \e[94m
grep: brackets ([ ]) not balanced
I managed to be able to filter it by using just <number color>m
echo -e "Default \e[94mLight blue" | grep 94m
Default 94mLight blue
But it removes all color formatting, changes the output and also has the potential to match a lot of other text that is not just color formatting.
How can I accomplish it?
There are several places where this goes wrong:
The character [ has a special meaning for grep, unless you use the --fixed-strings (-F in short) option. So it needs to be quoted:
grep '\[94m'
There is also (seems to be?) no way to specify the Escape character (\e) directly for grep with \e, \033 or something similar. But you can use zsh's $'…' quoting to let zsh create the Escape character:
grep $'\e\\[94m'
Strings inside $'…' will be process like arguments to the print builtin. So \e will be replaced by the actual Escape character and \ needs to be doubled in order to get a single, quoted backslash.
Be sure to use grep without any options that change formatting, for example --color=auto. By default Oh-My-Zsh creates an alias named grep that includes this option, if it is available.
You can force zsh to use the command instead of an alias by prepending the command precommand modifier:
command grep
All in all the following command should do the trick:
echo -e "Default \e[94mLight blue" | command grep $'\e\\[94m'
Note 1: This requires zsh due to $'…'. A more portable version would be
echo -e "Default \e[94mLight blue" | command grep $(printf '\033\\[94m')
Note 2: Unless the log output sets color codes (also) at the beginning of each line or resets them at the end of the line, the coloration of the output may still be broken. In that case you may have to use awk in order to get a better result:
echo "Default \e[94mLight blue\nDefault \e[94mLight blue" |
awk '/\033\[94m/ {printf "%s\033[0m\n", $0}'
This appends the reset coder \e[0m to the end of each matching line when printing it. Note that awk (at least the GNU version) does not use \e to signifiy the Escape character, you have to use 033 instead.
You can check, whether grep is an alias with this command:
whence -v grep
It is also possible that the environment variable GREP_OPTIONS is set to include such options. To check this, you can run this command:
echo "${(t)GREP_OPTIONS}: $GREP_OPTIONS}"
This shows the type of GREP_OPTIONS followed by its value (type: value). If the type does not contain export or the value is empty there should be no problem.
You can try this
echo -e "Default \e[94mLight blue" | sed -n '/\[94m/p'
This printed colors for me in zsh. I couldn't manage to include the '\e'
Basically, say I have a command like grep which outputs color-coded results with a flag like -r. If I were to wrap this command within a shell script, upon running the script, the output won't have the same color-coded effect.
Is there any other way of making the shell script spit out results (on terminal) in the same color-coding without resorting to using tput or manual color coding?
To force color output from grep:
grep --color=always
From man grep:
--color[=WHEN], --colour[=WHEN]
Surround the matched (non-empty) strings,
matching lines, context lines, file names, line
numbers, byte offsets, and separators (for fields
and groups of context lines) with escape
sequences to display them in color on the
terminal. The colors are defined by the
environment variable GREP_COLORS. The deprecated
environment variable GREP_COLOR is still
supported, but its setting does not have
priority. WHEN is never, always, or auto.
just use Bash functions, like, say this one:
make()
{
pathpat="(/[^/]*)+:[0-9]+"
ccred=$(echo -e "\033[0;31m")
ccyellow=$(echo -e "\033[0;33m")
ccend=$(echo -e "\033[0m")
/usr/bin/make "$#" 2>&1 | sed -E -e "/[Ee]rror[: ]/ s%$pathpat%$ccred&$ccend%g" -e "/[Ww]arning[: ]/ s%$pathpat%$ccyellow&$ccend%g"
return ${PIPESTATUS[0]}
}
How to turn on or off colors in bash
by NIX CRAFT on NOVEMBER 4, 2006 · 1 COMMENT· LAST UPDATED NOVEMBER 4, 2006
in BASH SHELL
Q. How do I turn on or off file name colors in bash shell?
A. Most modern Linux distro comes with alias that defines colors for your file. However ls command is responsible for displaying color on screen for files, directories and other object.
By default, color is not used to distinguish types of files. You need to pass --color option to ls command.
Task: Turn off colors
Type the following command
$ ls --color=none
Or just remove alias with unalias command:
$ unalias ls
Task: Turn on colors
Use any of the following command:
$ ls --color=auto
$ ls --color=tty
You can add or remove ls alias from ~/.bash_profile or ~/.bashrc file.
this commands for bash that are working well
handy tput commands
tput bold - Bold effect
tput rev - Display inverse colors
tput sgr0 - Reset everything
tput setaf {CODE}- Set foreground color, see color {CODE} below
tput setab {CODE}- Set background color, see color {CODE} below
Colors {code} code for tput command
Color {code} Color
0 Black
1 Red
2 Green
3 Yellow
4 Blue
5 Magenta
6 Cyan
7 White
I've been trying to make tail a little more readable for server startups. My current command filters out most of the INFO and DEBUG messages from the startup:
tail -F ../server/durango/log/server.log | grep -e "ERROR" -e "WARN" -e "Shutdown" -e "MicroKernel" | grep --color=auto -E 'MicroKernel|$'
What I would like to do is craft something that would highlight WARN in yellow and ERROR in red, and MicroKernel in green. I tried just piping grep --color=auto multiple times, but the only color that survives is the last command in the pipe.
Is there a one liner to do this? Or even a many-liner?
yes, there is way to do this. That is, as long as your terminal supports ANSI escape sequences. This is most terminals that exist.
I think I don't need explain how to grep, sed etc. point is the color right?
see below, this will make
WARN yellow
ERROR red
foo green
here is example:
kent$ echo "WARN
ERROR
foo"|sed 's#WARN#\x1b[33m&#; s#ERROR#\x1b[31m&#; s#foo#\x1b[32m&#'
Note: \x1b is hexadecimal for the ESC character (^VEsc).
to see the result:
I wrote a script for this years ago. You can easily cover the case of multiple colors by piping successive invocations of highlight to each other.
From the README:
Usage: ./highlight [-i] [--color=COLOR_STRING] [--] <PATTERN0> [PATTERN1...]
This is highlight version 1.0.
This program takes text via standard input and outputs it with the given
perlre(1) pattern(s) highlighted with the given color. If no color option
is specified, it defaults to 'bold red'. Colors may be anything
that Perl's Term::ANSIColor understands. This program is similar to
"grep --color PATTERN" except both matching and non-matching lines are
printed.
The default color can be selected via the $HIGHLIGHT_COLOR environment
variable. The command-line option takes precedence.
Passing -i or --ignore-case will enable case-insensitive matching.
If your pattern begins with a dash ('-'), you can pass a '--' argument
after any options and before your pattern to distinguish it from an
option.
I have been using a tool called grc for this for years. works like a charm. It comes with some quite good templates for many standard log outputs and formats and it is easy to define your own.
A command I use often is
grc tail -f /var/log/syslog
It colorizes the syslog output so it is easy to spot errors (typically marked red.
Find the tool here:
https://github.com/garabik/grc
(it is also available as package for most common linux flavours).
I wrote TxtStyle, a small utility for colorising logs. You define regular expressions to highlight in ~/.txts.conf file:
[Style="example"]
!red: regex("error")
green: regex("\d{4}-\d\d-\d\d")
# ...
And then apply the styles:
txts -n example example.log
or you can also pipe the output
tail -f example.log | txts -n example
You can create a colored log instead of using a complex command.
For php is like this:
echo "^[[30;43m".$ip."^[[0m";
The key point is to use Ctrl-v ctrl-[ to input a green ^[ under insert mode in vim, direct input ^[ does not work.
More info here
My sample using awk. Match log format like: xxxx [debug] xxxxx xxxx xxxx
black=30m
red=31m
green=32m
yellow=33m
blue=34m
magenta=35m
cyan=36m
white=37m
blacklog="\"\033[$black\" \$0 \"\033[39m\""
redlog="\"\033[$red\" \$0 \"\033[39m\""
greenlog="\"\033[$green\" \$0 \"\033[39m\""
yellowlog="\"\033[$yellow\" \$0 \"\033[39m\""
bluelog="\"\033[$blue\" \$0 \"\033[39m\""
magentalog="\"\033[$magenta\" \$0 \"\033[39m\""
cyanlog="\"\033[$cyan\" \$0 \"\033[39m\""
whitelog="\"\033[$white\" \$0 \"\033[39m\""
trace="/\[trace\]/ {print $redlog}"
debug="/\[debug\]/ {print $magentalog}"
info="/\[info\]/ {print $greenlog}"
warning="/\[warning\]/ {print $bluelog}"
error="/\[error\]/ {print $yellowlog}"
yourcommand | awk "$trace $debug $info $warning $error"
Is possible to use sed to change the background color of tabs (or any other text), so that, for example, I could run something like the following?
somefunction | sed -e 's/(some pattern)/(set bg color)\1(unset bg color)/g'
Yes:
#!/bin/bash
norm_bg=$(tput sgr0)
red_bg=$(tput setab 1)
echo -e "foo\tbar\tbaz" | sed "s/\t/$red_bg $norm_bg/g"
See this link for other Color Codes (very bottom)
You can insert colorization directly within your sed script:
echo -e "foo\tbar\tbaz" | sed 's/\t/\o033[41m \o033[0m/g'
Explanation:
set background in red = \o033[41m or \x1B[41m or \c[[41m
reset colors = \o033[0m or \x1B[0m or \c[[0m
You can also read similar question/anwsers:
Escaping the '\' character in the replacement string in a sed expression.
For more info on color codes, refer to Arch wiki.
+1 for olibre.
This also works on osx and linux, bash and zsh using extquote.
echo My name is Chad. | sed -e 's/Chad/\'$'\033[31m&\033[(B\033[m/'