Удаление цветовых кодов ANSI из текстового потока

Удаление цветовых кодов ANSI из текстового потока

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

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'

решение1

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

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

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

Использование настроек macOS по умолчаниюsed

Майкпредполагает:

sed -e $'s/\x1b\[[0-9;]*m//g'

По умолчанию macOS sedне поддерживает специальные символы, \eкак указанослмипароход25в комментариях.

Установить gsed.

brew install gnu-sed

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

(OP означает Оригинальный постер)

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

Улучшения

Флаг -eнеобязателен для GNU sed, но обязателен для macOS по умолчанию sed:

sed 's/\x1b\[[0-9;]*m//g'           # Remove color sequences only

Том Хейлпредлагает также удалить все другие escape-последовательности, используя [a-zA-Z]вместо только буквы, mспецифичной для escape-последовательности графического режима (цвет):

sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'    # Remove all escape sequences

Но [a-zA-Z]может оказаться слишком широким и может удалить слишком много.Михал ФаленскииМигель Мотапредлагаем удалить только некоторые управляющие последовательности, используя [mGKH]и [mGKF]соответственно.

sed 's/\x1b\[[0-9;]*[mGKH]//g'      # Remove color and move sequences
sed 's/\x1b\[[0-9;]*[mGKF]//g'      # Remove color and move sequences
sed 's/\x1b\[[0-9;]*[mGKHF]//g'     # Remove all
Last escape
sequence
character   Purpose
---------   -------------------------------
m           Graphics Rendition Mode (including color)
G           Horizontal cursor move
K           Horizontal deletion
H           New cursor position
F           Move cursor to previous n lines

Бриттон Керинуказывает K(в дополнение к m) удаляет цвета из gccошибки/предупреждения. Не забудьте перенаправить gcc 2>&1 | sed....

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

Версия, установленная на некоторых операционных системах, может быть ограничена (например, macOS). Преимущество sedкоманды в том, что ее обычно проще устанавливать/обновлять на большем количестве операционных систем.perlАдам Кацпредлагает использовать \e(то же самое, что и \x1b) вПКРЕ.

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

perl -pe 's/\e\[[0-9;]*m//g'          # Remove colors only
perl -pe 's/\e\[[0-9;]*[mG]//g'
perl -pe 's/\e\[[0-9;]*[mGKH]//g'
perl -pe 's/\e\[[0-9;]*[a-zA-Z]//g'
perl -pe 's/\e\[[0-9;]*m(?:\e\[K)?//g' # Adam Katz's trick

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

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

Применение

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

решение2

Я нашел лучшее средство для удаления escape-последовательности, если вы используете MacOS. Проверьте это:

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

решение3

ansi2txt

https://unix.stackexchange.com/a/527259/116915

cat typescript | ansi2txt | col -b
  • ansi2txt: удалить цветовые коды ANSI
  • col -b: удалить ^Hили^M


обновление: о табуляции и пробелах col handle //упомянул @DanielF

〇. о colпробелах и табуляциях

col -bxзаменить '\t' на ' ', col -bhзаменить ' ' на '\t'.

// похоже, colнельзя сохранить пробелы/табуляции как есть, жаль.


0. оригинальная строка

$ echo -e '        ff\tww' | hd
00000000  20 20 20 20 20 20 20 20  66 66 09 77 77 0a        |        ff.ww.|

1. -h заменить пробелы на табуляции

$ echo -e '        ff\tww' | col -b | hd
00000000  09 66 66 09 77 77 0a                              |.ff.ww.|
$ echo -e '        ff\tww' | col -bh | hd
00000000  09 66 66 09 77 77 0a                              |.ff.ww.|
$ echo -e '        ff\tww' | col -bxh | hd
00000000  09 66 66 09 77 77 0a                              |.ff.ww.|

2. -x заменить табуляции на пробелы

$ echo -e '        ff\tww' | col -bx | hd
00000000  20 20 20 20 20 20 20 20  66 66 20 20 20 20 20 20  |        ff      |
00000010  77 77 0a                                          |ww.|
$ echo -e '        ff\tww' | col -bhx | hd
00000000  20 20 20 20 20 20 20 20  66 66 20 20 20 20 20 20  |        ff      |
00000010  77 77 0a                                          |ww.|

3. похоже, colнельзя сохранить пробелы и табуляции в том виде, в котором они есть.

решение4

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

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

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

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

Связанный контент