¿Programa que pasa STDIN a STDOUT con códigos de color eliminados?

64

Tengo un comando que produce resultados en color, y me gustaría canalizarlo a un archivo con los códigos de color eliminados. ¿Hay algún comando que funcione como, catexcepto que elimina los códigos de color? Planeo hacer algo como esto:

$ command-that-produces-colored-output | stripcolorcodes > outfile
Ryan Thompson
fuente
44
Puede ser un error que un programa produzca resultados en color, incluso cuando su salida se redirige a un archivo y no proporciona una opción para desactivarlo. Esperaría que cualquier programa que colorea su salida verifique isatty(stdin)antes de hacerlo. ¿Te importaría compartir cuál es ese programa?
alex
pasarlo cat- la prueba rápida que ejecuté grep --color=auto myusername /etc/passwdme da mi nombre de usuario en rojo con texto en blanco elsewhree. grep --color=auto myusername /etc/passwd | catme da un texto en blanco simple
ivanivan
1
Eso no es una solución. Solo funciona porque grep --color=autoevita la producción de color cuando la salida estándar no es un terminal. Estoy hablando de un comando que genera códigos de color incondicionalmente. (Como señala Alex anteriormente, dicho comportamiento es posiblemente un error, pero a veces necesitamos trabajar con un software imperfecto que no podemos solucionar fácilmente, y de eso se trata esta pregunta.)
Ryan Thompson,
Posiblemente relevante unix.stackexchange.com/questions/14684/…
Chris Stryczynski

Respuestas:

59

Uno pensaría que habría una utilidad para eso, pero no pude encontrarlo. Sin embargo, este Perl one-liner debería hacer el truco:

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

Ejemplo:

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

O, si desea un script, puede guardarlo como stripcolorcodes:

#! /usr/bin/perl

use strict;
use warnings;

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

Si desea eliminar solo los códigos de color y dejar solos cualquier otro código ANSI (como el movimiento del cursor), use

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

en lugar de la sustitución que utilicé anteriormente (que elimina todos los códigos de escape ANSI).

cjm
fuente
99
Como se menciona en un comentario a otra respuesta ( unix.stackexchange.com/questions/4527/… ), se extrajo esta expresión regular Term::ANSIColor. ¡Reconozca sus fuentes, por favor!
Forivall
2
¡reconoce tus fuentes!
Jürgen Paul
29

Eliminar códigos de color (caracteres especiales) con GNU sed

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

O

Tira secuencias de escape ANSI en Python

Instale el paquete Python colorama ( pip install colorama). Poner en stripcolorcodes:

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

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

Ejecutar chmod +x stripcolorcodes.

jfs
fuente
Esto es asombroso ¡Exactamente lo que necesitaba!
adivis12
El Python es un poco lento pero sedes impresionante :)
2
No probé python, pero la versión sed no elimina todos los colores. (No
probé
22

Si puede instalar el módulo Term :: ANSIColor , este script perl funciona:

#!/usr/bin/env perl
use Term::ANSIColor qw(colorstrip);
print colorstrip $_ while <>;
Ryan Thompson
fuente
55
Ahí es donde obtuve esa expresión regular de solo códigos de color. Pero instalar un módulo completo solo para esa expresión regular es un poco demasiado.
cjm
44
Meh, si configura cpanm correctamente, instala el módulo en aproximadamente 5 segundos.
Ryan Thompson,
No hay necesidad de escribir el script en el archivo. Simplemente ingrese:perl -mTerm::ANSIColor=colorstrip -n -e 'print colorstrip $_'
Jesse Glick
10

Si el sistema tiene acceso a NodeJS se podría instalar el paquete de nodo siguiente, strip-ansi-cli.

$ npm install -g strip-ansi-cli

Luego puede ejecutar su comando así:

$ command-that-produces-colored-output | strip-ansi > outfile
David McNamara
fuente
1
NodeJS es una gran dependencia, cuando hay soluciones que pueden usar lenguajes y herramientas ya presentes en la mayoría de los sistemas.
user137369
Además, esta es la solución más lento que aparece (ver aquí ) y es probable que va a notar la diferencia.
3

Este comando sed lo hizo por mí:

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

Ejemplo:

$ command-that-produces-colored-output | sed -r "s/\\^\\[(\\[[^@-~]+[@-~]|[0-9@-_]|%@)//g" > outfile
Ben
fuente
Esto no parece funcionar con la última versión de sed.
3

Puedes usar ac para esto. Debería ser más rápido que todo lo mencionado anteriormente (aunque perly seddebería ser decente). Aquí hay un ejemplo:

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

Como descargo de responsabilidad: la funcionalidad de filtrado de color la escribí yo.


fuente
3
un enlace a 'ac' sería útil. ;)
Vitaly Kushner
El acprograma parece estar aquí: hub.darcs.net/vmchale/fastcat
Michael Burr
1
$ command-that-produces-colored-output | ansifilter

... y si es necesario, (dnf, ...) install ansifilter

JJoao
fuente