it-swarm-eu.dev

Odstranění kontrolních znaků (včetně kódů / barev konzoly) z výstupu skriptu

Pomocí příkazu "skript" mohu zaznamenat interaktivní relaci na příkazový řádek. To však zahrnuje všechny kontrolní znaky a barevné kódy. Řídicí znaky (jako backspace) mohu odstranit pomocí „col -b“, ale nemůžu najít jednoduchý způsob, jak odstranit barevné kódy.

Všimněte si, že chci používat příkazový řádek běžným způsobem, takže tam nechci barvy deaktivovat - chci je pouze odstranit z výstupu skriptu. Také vím, že si můžu hrát a zkusit najít regexp, který věci opraví, ale doufám, že existuje jednodušší (a spolehlivější - co když existuje kód, o kterém nevím, když vyvíjím regexp?) Řešení.

Chcete-li ukázat problém:

 spl62 tmp: script 
 Skript byl spuštěn, soubor je TypeScript 
 spl62 lepl: ls 
 add-license.sed build-example.sh commit-test Push-docs .sh 
 add-licence.sh build.sh delete-license.sed setup.py 
 asn build-test.sh delete-licence.sh src 
 build-doc.sh clean doc-src test.ini 
 spl62 lepl: exit 
 Skript byl dokončen, soubor je TypeScript 
 spl62 tmp: cat -v TypeScript 
 Skript byl zahájen Čt 9. června 2011 09:47:27 AM CLT 
 Spl62 lepl: ls ^ M 
 ^ [[0m ^ [[00madd-license.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-license.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 
 
 Skript proveden Čt 09 Červen 2011 09:47:29 AM CLT 
 Spl62 tmp: col -b <TypeScript 
 Skript byl zahájen Čt 9. června 2011 09:47:27 AM CLT 
 Spl62 lepl: ls 
 0m00madd-licence.sed0m 00; 32mbuild-example.sh0m 00mcommit-test0m 00; 32mpush-docs.sh0m 
 00; 32madd-license.sh0m 00; 32mbuild.sh0m 00metete-license.sed0m 00msetup .p0m 
 01; 34masn0m 00; 32mbuild-test.sh0m 00; 32mdelete-license.sh0m 01; 34msrc0m [.____] 00; 32mbuild-doc.sh0m 00; 32mclean0m 01; 34mdoc-src0m 00mtest.ini0m 
 spl62 lepl: exit 
 
 Skript vytvořen Čt 9. června 2011 09:47:29 CLT 
71
andrew cooke

Následující skript by měl odfiltrovat všechny řídicí sekvence ANSI/VT100/xterm pro (na základě ctlseqs ). Minimálně otestováno, nahlaste prosím všechny případy nedostatečné nebo nadměrné shody.

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

Známé problémy:

  • Nestěžuje si na chybné sekvence. To není to, pro co je tento skript určen.
  • Argumenty víceřádkových řetězců DCS/PM/APC/OSC nejsou podporovány.
  • Bajty v rozsahu 128–159 mohou být analyzovány jako kontrolní znaky, i když se to zřídka používá. Zde je verze, která analyzuje řídicí znaky mimo ASCII (v některých kódováních, včetně UTF-8, bude upravovat text, který není ASCII).
#!/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;
}

Aktualizace Gillesovy odpovědi, aby také odstranila návraty vozíku a vymazala předchozí znaky z backspace, což pro mě bylo důležité pro TypeScript generovaný na 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

V tomto případě bych použil sed.

dělat:

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

sed -e "s/search/nahradit/g" je standardní materiál. regex je vysvětleno níže:

\x1b shoduje se s Escape, který předchází barevnému kódu \[ odpovídá první otevřené závorce .\{1,5\} odpovídá 1 až 5 libovolného jediného znaku. Muset \ složené rovnátka, aby Shell zabránil jejich manglování. m poslední znak v regexu - obvykle sleduje barevný kód. // prázdný řetězec, který má nahradit vše. g se shoduje vícekrát na řádek.

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

=> jak používat:

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

testováno na: - AIX 5.x/6.1/7.1 - Linux Mandrake/Mandriva/SLES/Fedora - SunOS

6
scavenger

Existuje ansi2txt příkaz v colorized-logs balíček na Ubuntu. Odstraňuje pěkně barevné kódy ANSI, ale nezabývá se věcmi, jako jsou ukazatele průběhu vytvořené emitováním ^H nebo ^M znaky pro přepsání textu na místě. col -b se s nimi vypořádá , takže pro dosažení nejlepších výsledků můžete tyto dva kombinovat

cat TypeScript | ansi2txt | col -b
5
Marius Gedminas

Problém jsem vyřešil spuštěním scriptreplay na obrazovce a uložením vyrovnávací paměti scrollback do souboru.

Následující skript očekávání to provede za vás.

Byl testován na logfiles s až 250 000 řádky. V pracovním adresáři potřebujete skriptový skript, soubor nazvaný „čas“ s 10 000 000 krát řádek „1 10“ a skript. Jako argument příkazového řádku potřebuji název vašeho souboru skriptu, například ./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

Časový soubor může být vygenerován pomocí

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

Raději bych pomocí specializovaných nástrojů převedl výstup skriptu na prostý text, který je neustále podporován a dobře testován, přes vlastní regexp. Takže to pro mě udělalo práci:

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

příkaz skriptu zachycuje do souboru TypeScript ansi2txt - převádí kód ansi s úniky, jako jsou barevné kódy, backspace atd., na normální text, ale zjistil jsem, že pár útěků stále zbývá. col-bp - zcela je odstranil.

Testoval jsem to na nejnovější disko Ubuntu a funguje to.

1
Dmytro Brazhnyk

Zjistil jsem, že právě pomocí cat bylo vše, co jsem potřeboval k zobrazení výstupu script v terminálu. To nepomůže při přesměrování výstupu do jiného souboru, ale na rozdíl od cat -v, col -b nebo textový editor.

Chcete-li vyloučit barvy nebo uložit výsledky do souboru, zkopírujte a vložte výstup z cat do textového editoru nebo do jiného příkazu cat, tj .:

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

Tuto otázku našel při hledání řešení stejného problému. Trochu víc kopání a našel tento skript v Live Journal na tomto odkazu. Dokonale jsem pro mě pracoval. Je to také velmi dobrý zápis o tomto problému ao tom, jak řešení funguje. Rozhodně stojí za přečtení. 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

Ačkoli dosud uvedená řešení fungují pěkně na odstranění kontrolních sekvencí, odstraní také formátovací kódy. Výsledkem je, že tabulky ve výstupu jsou seskupeny dohromady. Mým požadavkem bylo pouze umožnit prohlížení a vyhledávání v souborech protokolu relací shromážděných z terminálu. Nejlepší řešení pro mě bylo použití méně -r.

less -r session.log
0
AliA