Программа, которая передает STDIN в STDOUT с раздетыми цветовыми кодами?

64

У меня есть команда, которая производит вывод в цвете, и я хотел бы передать его в файл с вычеркнутыми кодами цвета. Есть ли команда, которая работает как, catкроме того, что она удаляет цветовые коды? Я планирую сделать что-то вроде этого:

$ command-that-produces-colored-output | stripcolorcodes > outfile
Райан Томпсон
источник
4
Это может быть ошибкой в ​​том, что программа выдает цветной вывод, даже если ее вывод перенаправляется в файл и не позволяет отключить его. Я ожидаю, что любая программа, которая раскрашивает свои выходные данные, проверяет isatty(stdin)перед этим. Хотите поделиться, что это за программа?
Алекс
пройти его cat- быстрый тест, который я провел, grep --color=auto myusername /etc/passwdдает мне мое имя пользователя красным с белым текстом в другом месте. grep --color=auto myusername /etc/passwd | catдает мне простой белый текст
ivanivan
1
Это не решение. Это работает только потому, что grep --color=autoпозволяет избежать цветного вывода, когда стандартный вывод не является терминалом. Я говорю о команде, которая безоговорочно выводит цветовые коды. (Как указывает Алекс выше, такое поведение, возможно, является ошибкой, но иногда нам нужно работать с несовершенным программным обеспечением, которое мы не можем легко исправить самостоятельно, и вот о чем этот вопрос.)
Райан Томпсон
Возможно актуально unix.stackexchange.com/questions/14684/…
Крис Стрычински

Ответы:

59

Можно подумать, что для этого найдется полезность, но я не смог ее найти. Тем не менее, этот Perl однострочный должен сделать свое дело:

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

Пример:

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

Или, если вы хотите скрипт, вы можете сохранить как stripcolorcodes:

#! /usr/bin/perl

use strict;
use warnings;

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

Если вы хотите удалить только цветовые коды и оставить любые другие коды ANSI (например, перемещение курсора), используйте

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

вместо замены, которую я использовал выше (которая удаляет все управляющие коды ANSI).

CJM
источник
9
Как упоминалось в комментарии к другому ответу ( unix.stackexchange.com/questions/4527/… ), это регулярное выражение было удалено из Term::ANSIColor. Подтвердите ваши источники, пожалуйста!
Forivall
2
признать ваши источники!
Юрген Павел
29

Удалить цветовые коды (специальные символы) с помощью GNU sed

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

Или же

Обрезать escape-последовательности ANSI в Python

Установить пакет colorama python ( pip install colorama). Положить в stripcolorcodes:

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

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

Беги chmod +x stripcolorcodes.

JFS
источник
Это круто. Именно то, что мне было нужно!
adivis12
Python немного медленный, но sedвпечатляет :)
2
Не пробовал python, но версия sed не разделила все цвета. (Я не тестировал исчерпывающе, но некоторые цвета фона остались без изменений, поэтому я выбрал более быстрый вариант Perl.)
rsaw
22

Если вы можете установить модуль Term :: ANSIColor , этот скрипт на Perl работает:

#!/usr/bin/env perl
use Term::ANSIColor qw(colorstrip);
print colorstrip $_ while <>;
Райан Томпсон
источник
5
Это на самом деле, где я получил это регулярное выражение только для цветовых кодов. Но установка всего модуля только для этого регулярного выражения - это немного.
CJM
4
Мех, если вы правильно настроили cpanm, он установит модуль примерно за 5 секунд.
Райан Томпсон
Нет необходимости писать скрипт в файл. Просто трубка в:perl -mTerm::ANSIColor=colorstrip -n -e 'print colorstrip $_'
Джесси Глик
10

Если ваша система имеет доступ к NodeJS вы можете установить следующий пакет Node, strip-ansi-cli.

$ npm install -g strip-ansi-cli

Затем вы можете запустить свою команду следующим образом:

$ command-that-produces-colored-output | strip-ansi > outfile
Дэвид Макнамара
источник
1
NodeJS - это огромная зависимость, когда есть решения, которые могут использовать языки и инструменты, уже присутствующие в большинстве систем.
user137369
Кроме того, это самое медленное решение из перечисленных (см. Здесь ), и вы, вероятно , заметите разницу.
3

Эта команда sed сделала это для меня:

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

Пример:

$ command-that-produces-colored-output | sed -r "s/\\^\\[(\\[[^@-~]+[@-~]|[0-9@-_]|%@)//g" > outfile
Бен
источник
Это не похоже на работу с последней версией sed.
3

Вы можете использовать AC для этого. Это должно быть быстрее, чем все перечисленное выше (хотя perlи sedдолжно быть приличным). Вот пример:

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

Отказ от ответственности: функциональность цветовой фильтрации была написана мной.


источник
3
будет полезна ссылка на 'ac'. ;)
Виталий Кушнер
acПрограмма , кажется, здесь: hub.darcs.net/vmchale/fastcat
Michael Burr
1
$ command-that-produces-colored-output | ansifilter

... и при необходимости, (dnf, ...) install ansifilter

JJoao
источник