it-swarm-ru.tech

Удаление контрольных символов (включая коды / цвета консоли) из вывода скрипта

Я могу использовать команду "script" для записи интерактивного сеанса в командной строке. Однако сюда входят все управляющие символы и цветовые коды. Я могу удалить управляющие символы (например, backspace) с помощью "col -b", но я не могу найти простой способ удаления цветовых кодов.

Обратите внимание, что я хочу использовать командную строку обычным способом, поэтому не хочу отключать цвета там - я просто хочу удалить их из вывода скрипта. Кроме того, я знаю, что могу поиграть и попытаться найти регулярное выражение, чтобы исправить ситуацию, но я надеюсь, что есть более простое (и более надежное - что, если есть код, о котором я не знаю, когда разрабатываю регулярное выражение?).

Чтобы показать проблему:

 spl62 tmp: script 
 Сценарий запущен, файл - TypeScript 
 spl62 lepl: ls 
 add-licence.sed build-example.sh commit-test Push-docs .sh 
 add-licence.sh build.sh delete-licence.sed setup.py 
 asn build-test.sh delete-licence.sh src 
 build-doc.sh clean doc-src test.ini 
 spl62 lepl: выход 
 Сценарий выполнен, файл - TypeScript 
 spl62 tmp: cat -v TypeScript 
 Сценарий запущен в четверг 09 июня 2011 09:47:27 AM CLT 
 Spl62 lepl: ls ^ M 
 ^ [[0m ^ [[00madd-licence.sed ^ [[0m ^ [[00; 32mbuild-example.sh] ^ [[0m ^ [[00mcommit-test ^ [[0m ^ [[00; 32mpush-docs.sh ^] [[0m ^ M 
 ^ [[00; 32madd-licence.sh ^ [[0m ^ [[00; 32mbuild.sh ^ [[0m ^ [[00mdelete-licence.sed ^ [[0m ^ [[00msetup.py ^ [[0m ^ M 
 ^ [[01; 34masn ^ [[0m] ^ [[00; 32mbuild-test.sh ^ [[0m ^ [[00; 32mdelete-licence.sh ^ [[0m ^ [[01; 34msrc ^ [[0m ^ M 
 ^ [[00; 32mbuild-doc.sh ^ [[0m ^ [[00; 32mclean ^ [[0m ^ [[01; 34mdoc-src ^ [[0m ^ [[00mtest.ini ^ [[0m ^ M 
 Spl62 lepl: выход ^ M 
 
 Сценарий выполнен в чт 09 Июнь 2011 09:47:29 AM CLT 
 Spl62 tmp: col -b <TypeScript 
 Сценарий начался в четверг 09 июня 2011 09:47:27 CLT 
 Spl62 lepl: ls 
 0m00madd-licence.sed0m 00; 32mbuild-example.sh0m 00mcommit-test0m 00; 32mpush-docs.sh0m 
 00; 32madd-licence.sh0m 00; 32mbuild.sh0m 00mdelete-licence.sed0m 00msetup .py0m 
 01; 34masn0m 00; 32mbuild-test.sh0m 00; 32mdelete-licence.sh0m 01; 34msrc0m 
 00; 32mbuild-doc.sh0m 00; 32mclean0m 01; 34mdoc-src0m 00mtest.ini0m 
 spl62 lepl: выход 
 
 Сценарий сделан в четверг 09 июня 2011 09:47:29 CLT 
71
andrew cooke

Следующий скрипт должен отфильтровать все управляющие последовательности ANSI/VT100/xterm для (на основе ctlseqs ). Минимально проверено, пожалуйста, сообщите о любом недостаточном или чрезмерном совпадении.

#!/usr/bin/env Perl
## uncolor — remove terminal escape sequences such as color changes
while (<>) {
    s/ \e[ #%()*+\-.\/]. |
       \e\[ [ -?]* [@-~] | # CSI ... Cmd
       \e\] .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL)
       \e[P^_] .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST
       \e. //xg;
    print;
}

Известные вопросы:

  • Не жалуется на неправильно сформированные последовательности. Это не то, для чего этот сценарий.
  • Многострочные строковые аргументы для DCS/PM/APC/OSC не поддерживаются.
  • Байты в диапазоне 128–159 могут быть проанализированы как управляющие символы, хотя это редко используется. Вот версия, которая анализирует не-ASCII управляющие символы (это будет искажать не-ASCII-текст в некоторых кодировках, включая UTF-8).
#!/usr/bin/env Perl
## uncolor — remove terminal escape sequences such as color changes
while (<>) {
    s/ \e[ #%()*+\-.\/]. |
       (?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd
       (?:\e\]|\x9d) .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL)
       (?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST
       \e.|[\x80-\x9f] //xg;
    print;
}
58

Обновление ответа Жиля, чтобы также убрать возврат каретки и удалить назад символы, которые были важны для меня для TypeScript, сгенерированного на Cygwin:

#!/usr/bin/Perl
while (<>) {
    s/ \e[ #%()*+\-.\/]. |
       \r | # Remove extra carriage returns also
       (?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd
       (?:\e\]|\x9d) .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL)
       (?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST
       \e.|[\x80-\x9f] //xg;
       1 while s/[^\b][\b]//g;  # remove all non-backspace followed by backspace
    print;
}
31
dewtell

Я бы использовал sed в этом случае.

делать:

cat -v TypeScript | sed -e "s/\x1b\[.\{1,5\}m//g"

sed -e "s/search/replace/g" является стандартным материалом. регулярное выражение объясняется как показано ниже:

\x1b соответствует Escape, предшествующий цветовому коду \[ соответствует первой открытой скобке .\{1,5\} соответствует 1-5 любому отдельному символу. Должен \ фигурные скобки, чтобы Шелл не мог покалечить их. m последний символ в регулярном выражении - обычно завершает код цвета. // пустая строка для того, чтобы заменить все. g соответствует ему несколько раз в строке.

12
Glorytoad
cat TypeScript | Perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' | col -b > TypeScript-processed
9
Peter Nore
# The "sed -r" trick does not work on every Linux, I still dunno why:
DECOLORIZE='eval sed "s,${END}\[[0-9;]*[m|K],,g"'

=> Как использовать:

<commands that type colored output> | ${DECOLORIZE}

протестировано на: - AIX 5.x/6.1/7.1 - Linux Mandrake/Mandriva/SLES/Fedora - SunOS

6
scavenger

Там ansi2txt команда в colorized-logs пакет в Ubuntu. Он удаляет цветовые коды ANSI, но не работает с такими вещами, как индикаторы выполнения, генерируемые с помощью ^H или ^M символы для перезаписи текста на месте. col -b может справиться с этими , поэтому для достижения наилучших результатов вы можете объединить два

cat TypeScript | ansi2txt | col -b
5
Marius Gedminas

Я решил проблему, запустив scriptreplay на экране и выгрузив буфер обратной прокрутки в файл.

Следующий ожидаемый скрипт сделает это за вас.

Он был протестирован для лог файлов с 250 000 строк. В рабочем каталоге вам нужен ваш скрипт-файл, файл с именем time, в котором 10.000.000 раз строка "1 10", и скрипт. Мне нужно имя вашего файла сценария в качестве аргумента командной строки, как ./name_of_script name_of_scriptlog.

#!/usr/bin/expect -f 

set logfile [lindex $argv 0]

if {$logfile == ""} {puts "Usage: ./script_to_readable.exp \$logfile."; exit}

set timestamp [clock format [clock sec] -format %Y-%m-%d,%H:%M:%S]
set pwd [exec pwd]
if {! [file exists ${pwd}/time]} {puts "ERROR: time file not found.\nYou need a file named time with 10.000.000 times the line \"1 10\" in the working directory for this script to work. Please provide it."; exit}
set wc [exec cat ${pwd}/$logfile | wc -l]
set height [ expr "$wc" + "100" ]
system cp $logfile ${logfile}.tmp
system echo $timestamp >> ${logfile}.tmp
set timeout -1
spawn screen -h $height -S $timestamp 
send "scriptreplay -t time -s ${logfile}.tmp 100000 2>/dev/null\r"
expect ${timestamp} 
send "\x01:hardcopy -h readablelog.${timestamp}\r"

send "exit\r"

system sed '/^$/d' readablelog.$timestamp >> readablelog2.$timestamp
system head -n-2 readablelog2.$timestamp >> ${logfile}.readable.$timestamp
system rm -f readablelog.$timestamp readablelog2.$timestamp ${logfile}.tmp

Файл времени может быть сгенерирован

for i in $(seq 1 10000000); do echo "1 10" >> time; done
3
hnkchnsk

Я бы предпочел использовать специализированные инструменты для преобразования вывода скрипта в простой текст, который постоянно поддерживается и хорошо проверяется, по сравнению с пользовательским регулярным выражением. Так что это сделало работу для меня:

$ cat TypeScript | ansi2txt | col -bp > TypeScript.txt.bp    
$ cat -v TypeScript.txt.bp

команда script записывает в файл TypeScript ansi2txt - преобразует код ANSI с экранированием, таким как цветовые коды, символы возврата и т. д., в обычный текст, однако я обнаружил, что пара экранировок все еще остается. col-bp - удалил их полностью.

Я проверил это на последней дискотеке Ubuntu, и это работает.

1
Dmytro Brazhnyk

Я обнаружил, что только использование cat - это все, что мне нужно для просмотра вывода script в терминале. Это не помогает при перенаправлении вывода в другой файл, но делает результат читаемым, в отличие от cat -v, col -b или текстовый редактор.

Чтобы исключить цвета или сохранить результаты в файл, вручную скопируйте и вставьте выходные данные из cat в текстовый редактор или в другую команду cat, т.е.

cat > endResult << END
<paste_copied_text_here>
END
1
Roger Dueck

Нашел этот вопрос, пока искал решение той же проблемы. Еще немного покопаться и найти этот скрипт в Live Journal по этой ссылке. Я работал отлично для меня. Это также очень хорошая статья об этой проблеме и о том, как работает ее решение. Определенно стоит прочитать. http://jdimpson.livejournal.com/7040.html

#!/usr/bin/Perl -wp

# clean up control characters and other non-text detritus that shows up 
# when you run the "script" command.

BEGIN {
# xterm titlebar escape sequence
$xtermesc = "\x1b\x5d\x30\x3b";

# the occurence of a backspace event (e.g. cntrl H, cntrol W, or cntrl U)
$backspaceevent = "\x1b\\\x5b\x4b"; # note escaping of third character

# ANSI color escape sequence
$ansiesc = qr/\x1b\[[\d;]*?m/;

# technically, this is arrow-right. For some reason, being used against
# very long backspace jobs. I don't fully understand this, as evidenced
# by the fact that is off by one sometimes.
$bizarrebs = qr/\x1b\[C/;

# used as part of the xterm titlebar mechanism, or when
# a bell sounds, which might happen when you backspace too much.
$bell = "\x07"; # could use \a

$cr = "\x0d"; # could use \r

$backspace = "\x08"; # could use \b
}

s/$xtermesc.+?$bell//g;
s/[$cr$bell]//g;
s/${backspaceevent}//g;
s/$ansiesc//g;
while (s/(.)(?=$backspace)//) { s/$backspace//; } # frickin' sweet 
# For every ^H delete the character immediately left of it, then delete the ^H.
# Perl's RE's aren't R, so I wonder if I could do this in one expression.
while (s/(..)(?=$bizarrebs)//) { s/$bizarrebs//; }
1
SammerV

Хотя приведенные выше решения прекрасно работают для удаления управляющих последовательностей, они также удаляют коды форматирования. В результате таблицы в выходных данных сведены вместе. Моим требованием было просто иметь возможность просматривать и искать в файлах журнала сеансов, собранных с терминала. Лучшее решение для меня - использовать менее -r.

less -r session.log
0
AliA