Програма, яка передає STDIN в STDOUT з позбавленими кольорів кодами?


64

У мене є команда, яка виробляє вихід у кольорі, і я хотів би передати його у файл із викресленими кольоровими кодами. Чи існує така команда, яка працює catза винятком того, що знімає кольорові коди? Я планую зробити щось подібне:

$ command-that-produces-colored-output | stripcolorcodes > outfile

4
Можливо, помилка в тому, що програма виробляє кольоровий вихід, навіть тоді, коли його вихід перенаправляється на файл і не дає можливості його вимикати. Я б очікував, що будь-яка програма, кольори якої є вихідною, перевіряє, isatty(stdin)перш ніж це робити. Ви можете поділитися, що це за програма?
alex

пройди це cat- швидкий тест, який я пробіг, grep --color=auto myusername /etc/passwdдає мені своє ім’я користувача червоного кольору з білим текстом elsewhree. grep --color=auto myusername /etc/passwd | catдає мені звичайний білий текст
ivanivan

1
Це не рішення. Це працює лише тому, що grep --color=autoуникає отримання кольорового виводу, коли стандартний вихід не є терміналом. Я говорю про команду, яка беззастережно виводить кольорові коди. (Як Алекс зазначає вище, така поведінка, мабуть, є помилкою, але іноді нам потрібно працювати з недосконалим програмним забезпеченням, яке ми не можемо легко виправити, і ось в чому це питання.)
Ryan Thompson

Відповіді:


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).


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"

Або

Стрипіть послідовності втечі 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.


Це круто. Саме те, що мені було потрібно!
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 - це величезна залежність, коли є рішення, які можуть використовувати мови та засоби, які вже є у більшості систем.
користувач137369

Крім того, це найповільніше рішення, перераховане (див. Тут ), і ви, мабуть , помітите різницю.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.