Program, który przekazuje STDIN do STDOUT z usuniętymi kodami kolorów?

64

Mam polecenie, które generuje dane wyjściowe w kolorze, i chciałbym przesłać je do pliku z usuniętymi kodami kolorów. Czy istnieje takie polecenie, które działa tak cat, że usuwa kody kolorów? Planuję zrobić coś takiego:

$ command-that-produces-colored-output | stripcolorcodes > outfile
Ryan Thompson
źródło
4
Może to być błąd, w wyniku którego program generuje kolorowe dane wyjściowe, nawet jeśli dane wyjściowe są przekierowywane do pliku i nie zapewnia opcji wyłączenia go. Spodziewałbym się, że każdy program, który pokoloruje jego wyjście, sprawdzi isatty(stdin)przedtem. Chcesz podzielić się tym, czym jest ten program?
alex
przekazać go cat- szybki test, który przeprowadziłem, grep --color=auto myusername /etc/passwddaje mi moją nazwę użytkownika w kolorze czerwonym z białym tekstem w innym przypadku. grep --color=auto myusername /etc/passwd | catdaje mi zwykły biały tekst
ivanivan
1
To nie jest rozwiązanie. Działa to tylko dlatego, że grep --color=autopozwala uniknąć tworzenia kolorowych wydruków, gdy standardowe wyjście nie jest terminalem. Mówię o poleceniu, które bezwarunkowo wyświetla kody kolorów. (Jak podkreśla Alex powyżej, takie zachowanie jest prawdopodobnie błędem, ale czasami musimy pracować z niedoskonałym oprogramowaniem, którego sami nie jesteśmy w stanie łatwo naprawić, i o to właśnie chodzi.)
Ryan Thompson
Prawdopodobnie odpowiedni unix.stackexchange.com/questions/14684/…
Chris Stryczyński

Odpowiedzi:

59

Można by pomyśleć, że byłoby na to narzędzie, ale nie mogłem go znaleźć. Jednak ten liniowiec Perl powinien załatwić sprawę:

perl -pe 's/\e\[?.*?[\@-~]//g'

Przykład:

$ command-that-produces-colored-output | perl -pe 's/\e\[?.*?[\@-~]//g' > outfile

Lub, jeśli chcesz skrypt, możesz zapisać jako stripcolorcodes:

#! /usr/bin/perl

use strict;
use warnings;

while (<>) {
  s/\e\[?.*?[\@-~]//g; # Strip ANSI escape codes
  print;
}

Jeśli chcesz usunąć tylko kody kolorów i pozostawić wszystkie inne kody ANSI (np. Ruch kursora) w spokoju, użyj

s/\e\[[\d;]*m//g;

zamiast podstawienia, którego użyłem powyżej (który usuwa wszystkie kody specjalne ANSI).

cjm
źródło
9
Jak wspomniano w komentarzu do innej odpowiedzi ( unix.stackexchange.com/questions/4527/… ), ten regex został pobranyTerm::ANSIColor . Podaj swoje źródła, proszę!
forivall
2
potwierdź swoje źródła!
Jürgen Paul
29

Usuń kody kolorów (znaki specjalne) za pomocą GNU sed

sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"

Lub

Usuń sekwencje specjalne ANSI w Pythonie

Zainstaluj pakiet colorama python ( pip install colorama). Umieść w stripcolorcodes:

#!/usr/bin/env python
import colorama, fileinput, sys;
colorama.init(strip=True);

for line in fileinput.input():
    sys.stdout.write(line)

Uruchom chmod +x stripcolorcodes.

jfs
źródło
To jest niesamowite. Dokładnie to, czego potrzebowałem!
adivis12
Python jest nieco powolny, ale sedrobi wrażenie :)
2
Nie próbowałem Pythona, ale wersja sed nie usuwa wszystkich kolorów. (Nie testowałem wyczerpująco, ale pozostawiło kilka kolorów tła nietkniętych, więc wybrałem opcję szybszego perla.)
rsaw 17.01.2018
22

Jeśli możesz zainstalować moduł Term :: ANSIColor , ten skrypt perla działa:

#!/usr/bin/env perl
use Term::ANSIColor qw(colorstrip);
print colorstrip $_ while <>;
Ryan Thompson
źródło
5
Właśnie tam mam regex oparty tylko na kodach kolorów. Ale instalacja całego modułu tylko dla tego jednego wyrażenia regularnego to trochę więcej.
cjm
4
Meh, jeśli poprawnie skonfigurujesz cpanm, zainstaluje moduł w około 5 sekund.
Ryan Thompson,
Nie ma potrzeby zapisywania skryptu w pliku. Po prostu podłącz do:perl -mTerm::ANSIColor=colorstrip -n -e 'print colorstrip $_'
Jesse Glick
10

Jeśli system ma dostęp do NodeJS można zainstalować następujący pakiet węźle strip-ansi-cli.

$ npm install -g strip-ansi-cli

Następnie możesz uruchomić polecenie tak:

$ command-that-produces-colored-output | strip-ansi > outfile
David McNamara
źródło
1
NodeJS jest ogromną zależnością, gdy istnieją rozwiązania, które mogą wykorzystywać języki i narzędzia już obecne w większości systemów.
user137369,
Ponadto, jest to najwolniejszy rozwiązanie wymienione (patrz tutaj ) i prawdopodobnie będzie zauważyć różnicę.
3

To polecenie sed zrobiło to dla mnie:

sed -r "s/\\^\\[(\\[[^@-~]+[@-~]|[0-9@-_]|%@)//g"

Przykład:

$ command-that-produces-colored-output | sed -r "s/\\^\\[(\\[[^@-~]+[@-~]|[0-9@-_]|%@)//g" > outfile
Ben
źródło
To nie wydaje się działać z najnowszą wersją sed.
3

Możesz do tego użyć ac . Powinno być szybsze niż cokolwiek wymienionego powyżej (choć perli sedpowinno być przyzwoite). Oto przykład:

curl -s wttr.in/LA | ac -s

Jako wyłączenie odpowiedzialności: funkcja filtrowania kolorów została napisana przeze mnie.


źródło
3
link do „ac” byłby pomocny. ;)
Witalij Kushner,
acProgram wydaje się być tutaj: hub.darcs.net/vmchale/fastcat
Michael Burr
1
$ command-that-produces-colored-output | ansifilter

... a jeśli to konieczne, (dnf, ...) install ansifilter

JJoao
źródło