it-swarm.it

Rimozione dei caratteri di controllo (inclusi i codici / i colori della console) dall'output dello script

Posso usare il comando "script" per registrare una sessione interattiva dalla riga di comando. Tuttavia, questo include tutti i caratteri di controllo e codici colore. Posso rimuovere i caratteri di controllo (come backspace) con "col -b", ma non riesco a trovare un modo semplice per rimuovere i codici colore.

Nota che voglio usare la riga di comando in modo normale, quindi non voglio disabilitare i colori lì - voglio solo rimuoverli dall'output dello script. Inoltre, so che può giocare e provare a trovare un regexp per sistemare le cose, ma spero che ci sia una soluzione più semplice (e più affidabile - cosa succede se c'è un codice che non conosco quando sviluppo la regexp?).

Per mostrare il problema:

 spl62 tmp: script 
 Script avviato, il file è 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: exit 
 Script completato, il file è TypeScript 
 spl62 tmp: cat -v TypeScript 
 Script avviato il Gio 09 giu 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: exit ^ M 
 
 Script fatto il Gio 09 Giu 2011 09:47:29 CLT 
 Spl62 tmp: col -b <TypeScript 
 Script avviato il gio 09 giu 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 00msetupup .py0m 
 01; 34masn0m 00; 32mbuild-test.sh0m 00; 32mdelete-licence.sh0m 01; 34msrc0m 
 00; 32mbuild-doc.sh0m 00; 32mclean0m 01; 34mdoc-src0m 00mtest.ini0 
 spl62 lepl: exit 
 
 Script fatto il gio 09 giu 2011 09:47:29 CLT 
71
andrew cooke

Il seguente script dovrebbe filtrare tutte le sequenze di controllo ANSI/VT100/xterm per (basato su ctlseqs ). Testato minimamente, si prega di segnalare qualsiasi sotto-o sovra-partita.

#!/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;
}

Problemi conosciuti:

  • Non si lamenta di sequenze malformate. Non è questo lo scopo di questo script.
  • Gli argomenti di stringa multilinea su DCS/PM/APC/OSC non sono supportati.
  • I byte nell'intervallo 128–159 possono essere analizzati come caratteri di controllo, sebbene questo sia usato raramente. Ecco una versione che analizza i caratteri di controllo non ASCII (questo manipolerà il testo non ASCII in alcune codifiche tra cui 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;
}

Aggiornamento della risposta di Gilles per rimuovere anche i ritorni a capo e cancellare il backspace dei caratteri precedenti, che erano entrambi importanti per me per un TypeScript generato su 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

Vorrei usare sed in questo caso.

fare:

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

sed -e "s/cerca/sostituisci/g" è roba standard. la regex è spiegata come di seguito:

\x1b corrisponde a Escape che precede il codice colore \[ corrisponde alla prima parentesi aperta .\{1,5\} corrisponde a 1 a 5 di ogni singolo carattere. Dovere \ le parentesi graffe per impedire a Shell di rovinarle. m ultimo carattere in regex - di solito traccia il codice colore. // stringa vuota per cosa sostituire tutto. g abbinalo più volte per riga.

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"'

=> howto use:

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

testato su: - AIX 5.x/6.1/7.1 - Linux Mandrake/Mandriva/SLES/Fedora - SunOS

6
scavenger

C'e 'un ansi2txt comando nel colorized-logs pacchetto su Ubuntu. Rimuove bene i codici colore ANSI, ma non si occupa di cose come le barre di avanzamento prodotte emettendo ^H o ^M caratteri per sovrascrivere il testo in atto. col -b può gestire quelli , quindi per ottenere i migliori risultati puoi combinare i due

cat TypeScript | ansi2txt | col -b
5
Marius Gedminas

Ho risolto il problema eseguendo scriptreplay in una schermata e scaricando il buffer di scorrimento su un file.

Il seguente script di attesa fa questo per te.

È stato testato per file di registro con un massimo di 250.000 righe. Nella directory di lavoro è necessario il tuo scriptlog, un file chiamato "time" con 10.000.000 volte la riga "1 10" e lo script. Ho bisogno del nome del tuo file di script come argomento della riga di comando, come ./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

Il file temporale può essere generato da

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

Preferirei usare strumenti specializzati per convertire l'output di script in testo semplice, che è costantemente supportato e ben testato, su regexp personalizzato. Quindi questo ha funzionato per me:

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

il comando script acquisisce nel file TypeScript ansi2txt - converte il codice ansi con escape come colorcodes, backspaces ecc. in testo normale, tuttavia ho scoperto che un paio di escape sono ancora rimasti. col -bp - li ha rimossi completamente.

L'ho provato sull'ultima discoteca Ubuntu e funziona.

1
Dmytro Brazhnyk

Ho scoperto che basta usare cat per visualizzare l'output di script nel terminale. Questo non aiuta quando si reindirizza l'output su un altro file, ma rende leggibile il risultato, a differenza di cat -v, col -b o un editor di testo.

Per eliminare i colori o salvare i risultati in un file, copia e incolla manualmente l'output da cat in un editor di testo o in un altro comando cat, ad es .:

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

Ho trovato questa domanda mentre cercavo una soluzione allo stesso problema. Un po 'più di ricerca e ho trovato questo script su Live Journal a questo link. Ho lavorato perfettamente per me. È anche un ottimo commento su questo problema e su come funziona la soluzione. Sicuramente merita una lettura. 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

Sebbene le soluzioni fornite finora funzionino bene per rimuovere le sequenze di controllo, tuttavia rimuovono anche i codici di formattazione. Il risultato è che le tabelle nell'output vengono schiacciate insieme. Il mio requisito era solo quello di essere in grado di visualizzare e cercare nei file di registro delle sessioni raccolti dal terminale. La soluzione che funziona meglio per me era usare meno -r.

less -r session.log
0
AliA