Leiten eines Befehls durch einen Farbfilter

13

Gibt es so etwas in Unix?

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

Hiermit meine ich nicht, dass wörtlicher Farbcodetext angezeigt wird (zum Beispiel, um in eine Datei eingefügt zu werden). Ich meine nur, dass der Text tatsächlich im Terminal als diese Farbe angezeigt wird. Ist das möglich?

George
quelle

Antworten:

14

Hier ist ein kleines Skript, das genau das macht. Speichern Sie dies als colorin einem Verzeichnis in Ihrem $PATH(zum Beispiel, ~/binwenn das in Ihrem ist $PATH):

#!/usr/bin/env perl

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

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

Führen Sie dann Ihren Text durch das Skript und geben Sie .als Muster für die Übereinstimmung eine Farbe an:

Screenshot eines Terminals, auf dem das Skript ausgeführt wird

Die unterstützten Farben hängen von den Fähigkeiten Ihres Terminals ab. Weitere Informationen finden Sie in der Dokumentation des Term::ANSIColorPakets.

terdon
quelle
Gibt es eine Liste von Farben, die irgendwo zugelassen sind?
George
@ George, das hängt von Ihrem Setup ab. Wenn Sie ein RGB-fähiges Endgerät besitzen, können Sie auch verwenden , um Dinge wie rgb001, rgb123usw. Siehe perldoc.perl.org/Term/ANSIColor.html#Supported-Colors für weitere Details.
Terdon
23

Sie würden dafür verwenden tput:

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

Dies kann verwendet werden, um eine Pipe zu bauen:

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

Die Grundfarben sind Schwarz (0), Rot (1), Grün, Gelb, Blau, Magenta, Cyan und Weiß (7). Sie finden alle Details in der terminfo(5)Manpage .

Stephen Kitt
quelle
6

Mit zsh:

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

Und dann:

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

(Wie in den Kommentaren besprochen, verwenden Sietput stattdessen, wenn Sie es haben.)

Mit Bourne - Shell und echo(eingebaut) Befehl, der den ANSI - Escape versteht \emit -eOption:

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

oder allgemeineres Shell-Skript (etwa /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=wird benötigt, um das Trimmen von Leerzeichen zu verhindern (siehe POSIX für Details).

wie IFS funktioniert

Wataash
quelle
Ich empfehle die Verwendung zu bevorzugen tput.
LinuxSecurityFreak
Dies ist keine tragbare Lösung. Ich meine, Sie sollten sich an POSIX halten.
LinuxSecurityFreak
1
Klar, wenn wir könnten. Es ist für eingebettete Systeme oder Rettungsumgebungen wie busybox vorgesehen. Ich habe mich dazu entschlossen, diese Antwort zu schreiben, da ich glaube, dass diese Codeausschnitte in einigen Situationen nützlich sind - zumindest für vielbeschäftigte Boxbenutzer und für mich, die heute Farben nur mit den in einer eingebetteten Umgebung integrierten Shell-Befehlen ausgeben mussten.
Wataash
habe vergessen zu sagen, dass die normale busybox keinen tput hat.
Wataash