Canalizar un comando a través de un filtro de color

13

¿Existe algo como esto en Unix?

$ echo "this should show in red" | red
$ echo "this should show in green" | green
$ echo "this should show in blue" | blue

Aquí no me refiero a que aparezca el texto literal del código de color (para pegarlo en un archivo, por ejemplo). Solo quiero decir que el texto se muestre en la terminal como ese color. es posible?

Jorge
fuente

Respuestas:

14

Aquí hay un pequeño guión que hace exactamente eso. Guarde esto como coloren un directorio en su $PATH(por ejemplo, ~/binsi está en su $PATH):

#!/usr/bin/env perl

use strict;
use warnings;
use Term::ANSIColor; 

my $color=shift;
while (<>) {
    print color("$color").$_.color("reset");
} 

Luego, pase su texto a través del guión, dando .el patrón para que coincida y especificando un color:

captura de pantalla de una terminal que ejecuta el script

Los colores admitidos dependen de las capacidades de su terminal. Para más detalles, consulte la documentación del Term::ANSIColorpaquete.

terdon
fuente
¿Hay una lista de colores que son válidos para pasar en algún lugar?
George
@ George que depende de su configuración. Si tiene un terminal compatible con RGB, incluso puede usar cosas como rgb001, rgb123etc. Consulte perldoc.perl.org/Term/ANSIColor.html#Supported-Colors para obtener más detalles.
terdon
23

Lo usarías tputpara eso:

tput setaf 1
echo This is red
tput sgr0
echo This is back to normal

Esto se puede usar para construir una tubería:

red() { tput setaf 1; cat; tput sgr0; }
echo This is red | red

Los colores básicos son respectivamente negro (0), rojo (1), verde, amarillo, azul, magenta, cian y blanco (7). Encontrarás todos los detalles en la página de terminfo(5)manual .

Stephen Kitt
fuente
6

Con zsh :

autoload colors; colors
for color (${(k)fg})
  eval "$color() {print -n \$fg[$color]; cat; print -n \$reset_color}"

Y entonces:

$ echo "while" | blue
while
Stéphane Chazelas
fuente
1

(como se discutió en los comentarios, usetput en su lugar si lo tiene)

Usando el shell bourne y el echocomando (incorporado) que comprende el escape ANSI \econ la -eopción:

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

o, script de shell más genérico (digamos /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=es necesario para evitar el recorte de espacios en blanco (ver POSIX para más detalles).

cómo funciona IFS

wataash
fuente
Aconsejo preferir usar tput.
LinuxSecurityFreak
Esta es una solución completamente no portátil. Quiero decir que debes adherirte a POSIX.
LinuxSecurityFreak
1
Claro, si pudiéramos. Está destinado a ser utilizado en sistemas integrados o entornos de rescate como busybox. Decidí escribir esta respuesta porque creo que estos fragmentos de código son útiles en algunas situaciones, al menos para los usuarios de busybox y para mí, que tuvieron que generar colores solo con los comandos integrados de shell en un entorno integrado hoy.
wataash
olvidé decir que busybox ordinario no tiene tput.
wataash