Piping a command through a color filter
Solution 1
Here's a little script that does just that. Save this as color
in a directory in your $PATH
(for example, ~/bin
if that's in your $PATH
):
#!/usr/bin/env perl
use strict;
use warnings;
use Term::ANSIColor;
my $color=shift;
while (<>) {
print color("$color").$_.color("reset");
}
Then, pass your text through the script, giving .
as the pattern to match and specifying a color:
The supported colors depend on the abilities of your terminal. For more details, see the documentation of the Term::ANSIColor
package.
Solution 2
You'd use tput
for that:
tput setaf 1
echo This is red
tput sgr0
echo This is back to normal
This can be used to build a pipe:
red() { tput setaf 1; cat; tput sgr0; }
echo This is red | red
The basic colours are respectively black (0), red (1), green, yellow, blue, magenta, cyan and white (7). You'll find all the details in the terminfo(5)
manpage.
Solution 3
With zsh
:
autoload colors; colors
for color (${(k)fg})
eval "$color() {print -n \$fg[$color]; cat; print -n \$reset_color}"
And then:
$ echo "while" | blue
while
Solution 4
(as discussed in comments, use tput
instead if you have it)
Using bourne shell and echo
(built-in) command which understands the ANSI escape \e
with -e
option:
black() { IFS= ; while read -r line; do echo -e '\e[30m'$line'\e[0m'; done; }
red() { IFS= ; while read -r line; do echo -e '\e[31m'$line'\e[0m'; done; }
green() { IFS= ; while read -r line; do echo -e '\e[32m'$line'\e[0m'; done; }
yellow() { IFS= ; while read -r line; do echo -e '\e[33m'$line'\e[0m'; done; }
blue() { IFS= ; while read -r line; do echo -e '\e[34m'$line'\e[0m'; done; }
purple() { IFS= ; while read -r line; do echo -e '\e[35m'$line'\e[0m'; done; }
cyan() { IFS= ; while read -r line; do echo -e '\e[36m'$line'\e[0m'; done; }
white() { IFS= ; while read -r line; do echo -e '\e[37m'$line'\e[0m'; done; }
echo ' foo\n bar' | red
or, more generic shell script (say, /usr/local/bin/colorize
):
#!/bin/sh
usage() {
echo 'usage:' >&2
echo ' some-command | colorize {black, red, green, yellow, blue, purple, cyan, white}' >&2
exit 1
}
[ -z "$1" ] && usage
case $1 in
black) color='\e[30m' ;;
red) color='\e[31m' ;;
green) color='\e[32m' ;;
yellow) color='\e[33m' ;;
blue) color='\e[34m' ;;
purple) color='\e[35m' ;;
cyan) color='\e[36m' ;;
white) color='\e[36m' ;;
*) usage ;;
esac
IFS=
while read -r line; do
echo -e $color$line'\e[0m'
done
IFS=
is needed to prevent whitespace trimming (see POSIX for details).
Related videos on Youtube
![Gaétan RYCKEBOER](https://lh4.googleusercontent.com/-neutQ_UmytM/AAAAAAAAAAI/AAAAAAAACvA/jjP1-WuOpTU/photo.jpg?sz=256)
Gaétan RYCKEBOER
Updated on September 18, 2022Comments
-
Gaétan RYCKEBOER almost 2 years
Does something like this exist in Unix?
$ echo "this should show in red" | red $ echo "this should show in green" | green $ echo "this should show in blue" | blue
Here I don't mean for literal color code text to come up (to be pasted in a file, for example). I just mean for the text to actually show up in the terminal as that color. Is this possible?
-
Gaétan RYCKEBOER about 8 yearsIs there a list of colors that are valid to pass in somewhere?
-
Vlastimil Burián almost 5 yearsThis is completely non-portable solution. I mean you should adhere to POSIX.
-
wataash almost 5 yearsSure, if we could. It's intended to be used on embedded systems or rescue environments like busybox. I decided to write this answer because I believe these code snippets are useful in some situations -- at least for busybox users and for me, who had to output colors only with shell's built-in commands on an embedded environment today.
-
wataash almost 5 yearsforgot to say that ordinary busybox doesn't have tput.
-
jvriesem about 4 yearsI don't know perl. Why doesn't
color rgb012
work and give me some kind of teal/turquoise color?