Передача команды через цветной фильтр

13

Существует ли что-то подобное в Unix?

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

Здесь я не имею в виду появление буквенного цветового кода (например, для вставки в файл). Я просто имею в виду, что текст будет отображаться в терминале как этот цвет. Это возможно?

Джордж
источник

Ответы:

14

Вот небольшой скрипт, который делает именно это. Сохраните это как colorв каталоге в вашем $PATH(например, ~/binесли это в вашем $PATH):

#!/usr/bin/env perl

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

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

Затем пропустите текст через скрипт, .указав в качестве шаблона для соответствия и указав цвет:

снимок экрана терминала, на котором запущен скрипт

Поддерживаемые цвета зависят от возможностей вашего терминала. Для более подробной информации смотрите документацию к Term::ANSIColorпакету.

Тердон
источник
Есть ли список цветов, которые допустимо передавать где-то?
Джордж
@ Джордж, который зависит от вашей настройки. Если у вас есть RGB-способный терминал, вы даже можете использовать вещи , как rgb001, и rgb123т.д. См perldoc.perl.org/Term/ANSIColor.html#Supported-Colors для более подробной информации.
Тердон
23

Вы бы использовали tputдля этого:

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

Это может быть использовано для построения трубы:

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

Основные цвета: черный (0), красный (1), зеленый, желтый, синий, пурпурный, голубой и белый (7). Вы найдете все подробности на terminfo(5)странице руководства .

Стивен Китт
источник
6

С zsh:

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

А потом:

$ echo "while" | blue
while
Стефан Шазелас
источник
1

(как описано в комментариях, используйтеtput вместо этого, если у вас есть)

Использование оболочки Bourne и echo(встроенной) команды, которая понимает экранирование ANSI \eс -eопцией:

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

или, более общий сценарий оболочки (скажем, /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=необходим для предотвращения обрезки пробелов (подробнее см. POSIX ).

как работает IFS

wataash
источник
Советую предпочесть использование tput.
LinuxSecurityFreak
Это абсолютно непереносимое решение. Я имею в виду, вы должны придерживаться POSIX.
LinuxSecurityFreak
1
Конечно, если бы мы могли. Он предназначен для использования во встроенных системах или в средах восстановления, таких как busybox. Я решил написать этот ответ, потому что считаю, что эти фрагменты кода полезны в некоторых ситуациях - по крайней мере, для пользователей busybox и для меня, которым сегодня приходилось выводить цвета только с помощью встроенных команд оболочки во встроенной среде.
wataash
забыл сказать, что у обычного busybox нет tput.
wataash