52

Изучение выходных от

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";'

в текстовом редакторе (например, vi) отображается следующее:

^[[37mABC
^[[0m

Как можно удалить цветовые коды ANSI из выходного файла? Я полагаю, что лучшим способом было бы передать вывод через своего рода потоковый редактор.

Следующее не работает

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' | perl -pe 's/\^\[\[37m//g' | perl -pe 's/\^\[\[0m//g'

9 ответов9

69

Символы ^[[37m и ^[[0m являются частью последовательности перехода ANSI (коды CSI).
Смотрите также полные спецификации.

Используя sed

sed 's/\x1b\[[0-9;]*m//g'
  • \x1b является побег специальный символ ( такой же , как \x1B или \033
  • \[ является вторым символом escape-последовательности
  • [0-9;]* - это значение цвета
  • m - последний символ escape-последовательности

Пример с командной строкой параметров порядка:(ОП = О Р первоначально оплащенная Oster)

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' | 
sed 's/\x1b\[[0-9;]*m//g'

Том Хейл предлагает удалить все другие escape-последовательности, используя [a-zA-Z] вместо буквы m специфичной для цветовой escape-последовательности. Но [a-zA-Z] может быть слишком широким и может удалить слишком много. Михал Фаленски и Мигель Мота предлагают удалить только некоторые escape-последовательности, используя [mGKH] и [mGKF] соответственно.

sed 's/\x1b\[[0-9;]*m//g'        # Remove color sequences only
sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' # Remove all escape sequences
sed 's/\x1b\[[0-9;]*[mGKH]//g'   # Remove color and move sequences
sed 's/\x1b\[[0-9;]*[mGKF]//g'   # Remove color and move sequences
Last escape
sequence
character   Purpose
---------   -------------------------------
m           Color
G           Horizontal cursor move
K           Horizontal deletion
H           New cursor position
F           Move cursor to previous n lines

Использование perl

Версия sed установленная в некоторых операционных системах, может быть ограничена (например, MacOS X). Преимущество команды perl состоит в том, что ее часто проще устанавливать / обновлять в более операционных системах.

Выберите свое регулярное выражение в зависимости от того, сколько команд вы хотите отфильтровать:

perl -pe 's/\x1b\[[0-9;]*m//g'        # Remove colors only
perl -pe 's/\x1b\[[0-9;]*[mG]//g'
perl -pe 's/\x1b\[[0-9;]*[mGKH]//g'
perl -pe 's/\x1b\[[0-9;]*[a-zA-Z]//g'

Пример с командной строкой OP:

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset"' \
  | perl -pe 's/\x1b\[[0-9;]*m//g'

использование

Как отмечается в комментарии Стюарта Кардалла , этот трюк используется проектом Ultimate Nginx Bad Bot (почти 1000 звезд) для очистки отчета по электронной почте ;-)

17

Я нашел лучший способ удаления последовательности побега. Проверь это:

perl -pe 's/\x1b\[[0-9;]*[mG]//g'

9

То, что отображается как ^[ это не ^ и [ ; это символ ASCII ESC , созданный с помощью Esc или Ctrl [ (обозначение ^ означает клавишу Ctrl).

ESC 0x1B шестнадцатеричный или 033 восьмеричный, поэтому вы должны использовать \x1B или \033 в своих регулярных выражениях:

perl -pe 's/\033\[37m//g; s/\033[0m//g'

perl -pe 's/\033\[\d*(;\d*)*m//g'
4

Если вы предпочитаете что-то простое, вы можете использовать модуль strip-ansi (требуется Node.js ):

$ npm install --global strip-ansi-cli

Затем используйте это так:

$ strip-ansi < colors.o

Или просто передайте строку:

$ strip-ansi '^[[37mABC^[[0m'
2

"Ответ" на вопрос не сработал, поэтому я вместо этого создал это регулярное выражение для удаления escape-последовательностей, создаваемых модулем perl Term::ANSIColor.

cat colors.o | perl -pe 's/\x1b\[[^m]+m//g;

Регулярное выражение Grawity должно работать нормально, но использование + тоже работает нормально.

2

commandlinefu дает этот ответ, который отбрасывает цвета ANSI, а также команды перемещения:

sed "s,\x1B\[[0-9;]*[a-zA-Z],,g"

Для только цветов, вы хотите:

 sed "s,\x1B\[[0-9;]*m,,g"
0

Я считаю, что это авторитетное удаление всех escape-последовательностей ANSI:

perl -pe '
  s/\e\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]//g;
  s/\e[PX^_].*?\e\\//g;
  s/\e\][^\a]*(?:\a|\e\\)//g;
  s/\e[\[\]A-Z\\^_@]//g;'

(Обратите внимание, что Perl, как и многие другие языки (но не sed), принимает \e в качестве escape-символа Esc, \x1b или \033 по коду, который отображается в терминалах как ^[ . Я использую это здесь, потому что это кажется более интуитивным.)

Эта команда perl, которую вы можете запустить все в одну строку, если хотите, содержит две замены. Первый идет после последовательностей CSI (последовательности escape-кодов, начинающиеся с "Представителя управляющих последовательностей" из Esc [, который охватывает гораздо больше, чем последовательности Select Graphic Rendition, которые составляют цветовые коды и другие текстовые декорации).

Вторая замена удаляет оставшиеся последовательности, которые включают в себя завершающие символы и оканчиваются на ST (терминатор строки, Esc \). Третья замена - это то же самое, но также позволяет завершать последовательности команд операционной системы с помощью BEL (\x07 , часто \a).

Четвертая замена удаляет оставшиеся побеги.

Также рассмотрите возможность удаления других символов ASCII нулевой ширины, таких как BEL и других более неясных управляющих символов C0 и C1. Я использую [\x00-\x1f\x7f-\x9f\xad] , который также включает Delete и Soft Hyphen. Это исключает более длинные закодированные символы Unicode с нулевой шириной, но я считаю, что это исчерпывающее значение для ASCII (Unicode \x00 - \xff). Если вы сделаете это, удалите эти последние, так как они могут быть включены в более длинные последовательности.

0

У меня была похожая проблема с удалением символов, добавленных из сбора интерактивного верхнего вывода через замазку, и это помогло:

cat putty1.log | perl -pe 's/\x1b.*?[mGKH]//g'
0

Это то, что у меня сработало (проверено на Mac OS X)

perl -pe 's/\[[0-9;]*[mGKF]//g'

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .