स्क्रिप्ट आउटपुट से नियंत्रण वर्ण (कंसोल कोड / रंग सहित) निकाल रहा है


68

मैं कमांड लाइन पर एक इंटरैक्टिव सत्र रिकॉर्ड करने के लिए "स्क्रिप्ट" कमांड का उपयोग कर सकता हूं। हालांकि, इसमें सभी नियंत्रण वर्ण और रंग कोड शामिल हैं। मैं "कॉल-बी" के साथ नियंत्रण वर्ण (जैसे बैकस्पेस) को हटा सकता हूं, लेकिन मुझे रंग कोड हटाने का एक सरल तरीका नहीं मिल सकता है।

ध्यान दें कि मैं कमांड लाइन को सामान्य तरीके से उपयोग करना चाहता हूं, इसलिए वहां रंगों को अक्षम नहीं करना चाहता हूं - मैं उन्हें स्क्रिप्ट आउटपुट से निकालना चाहता हूं। इसके अलावा, मुझे पता है कि चारों ओर खेल सकते हैं और चीजों को ठीक करने के लिए एक regexp ढूंढने का प्रयास कर सकते हैं, लेकिन मैं उम्मीद कर रहा हूं कि एक सरल (और अधिक विश्वसनीय है - क्या होगा अगर मुझे regexp विकसित करने के बारे में कोई कोड नहीं पता है?) समाधान।

समस्या दिखाने के लिए:

spl62 tmp: स्क्रिप्ट
स्क्रिप्ट शुरू हुई, फ़ाइल टाइपस्क्रिप्ट है
spl62 lepl: एल.एस.
add-licence.sed build-example.sh कमिट-टेस्ट पुश-docs.sh
add-licence.sh build.sh delete-licence.sed setup.py
asn build-test.sh delete-licence.sh src
build-doc.sh स्वच्छ doc-src test.ini
spl62 लेप: बाहर निकलें
स्क्रिप्ट की गई, फ़ाइल टाइपस्क्रिप्ट है
spl62 tmp: कैट -v टाइपस्क्रिप्ट
स्क्रिप्ट थू 09 जून 2011 09:47:27 पूर्वाह्न सीएलटी पर शुरू हुई
spl62 लेप: ls ^ एम
^ [[0 मी ^ [[00 ग्राम्ड-लाइसेंसेंस ^ ^ [[0m ^] [00; 32mbuild-example.sh ^ [[0m ^] [[00mcommit-test ^] [[0m ^] [00; 32mpush-docs.sh; ^ [[0m ^ एम
^ [[००; ३२ एएमडेल -डैलेंस.श ^ [[० एम।] [[००२; ३२ डीब्यूइल्ड.श ^ [[० एम ^] [[०० मी।
^ [[०१; ३४ वेंमन ^] [[० मी।
^ [[00; 32mbuild-doc.sh ^ [[0m ^ [[00; 32mclean ^] [[0m ^ [[01; 34mdoc-src ^] [[0m ^] [[00mtn.ini ^] [[0m ^ M;
spl62 लेप: बाहर निकलें ^ M

स्क्रिप्ट थू 09 जून 2011 09:47:29 पूर्वाह्न CLT पर की गई
spl62 tmp: col -b <टाइपस्क्रिप्ट 
स्क्रिप्ट थू 09 जून 2011 09:47:27 पूर्वाह्न सीएलटी पर शुरू हुई
spl62 lepl: एल.एस.
0m00madd-licence.sed0m 00; 32mbuild-example.sh0m 00mcommit-test0m 00; 32mpush-docs.sh0m
00; 32 एएमडी-लाइसेंस-एचएस 00 एम; 32mbuild.sh0m 00mdelete-licence.sed0m 00msetup.py0m
०१; ३४ नमास ० मी ००; ३२ ग्राम-परीक्षण-शश ० मी ००; ३२ मीट-लिटेंस-शश ०१ ०१; ३४ मी। आर्क ० मी ०;
00; 32mbuild-doc.sh0m 00; 32mclean0m 01; 34mdoc-src0m 00mtest.ini0m
spl62 लेप: बाहर निकलें

स्क्रिप्ट थू 09 जून 2011 09:47:29 पूर्वाह्न CLT पर की गई

जवाबों:


57

निम्न स्क्रिप्ट को सभी 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 की सीमा में बाइट्स को नियंत्रण पात्रों के रूप में पार्स किया जा सकता है, हालांकि इसका उपयोग शायद ही कभी किया जाता है। यहां एक संस्करण है जो गैर-एएससीआईआई नियंत्रण पात्रों को पार्स करता है (यह यूटीएफ -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;
}

दोनों उत्तर के लिए धन्यवाद। मैंने महसूस किया कि मुझे एक अच्छे उत्तर के रूप में कुछ बनाना चाहिए, हालांकि दोनों रीजैक्स देते हैं, जिससे मैं बचना चाहता था। इसे चुना क्योंकि यह प्रारूप के लिए एक संदर्भ देता है।
andrew cooke

@andrew: मेरा regexp काफी लचीला है कि मुझे उम्मीद है कि यह अब किसी भी मौजूदा टर्मिनल के साथ काम करेगा, और शायद किसी भी कल-मौजूदा टर्मिनल के साथ भी। मैंने इसका बहुत परीक्षण नहीं किया है, इसलिए कीड़े हो सकते हैं, लेकिन दृष्टिकोण ध्वनि है क्योंकि नियंत्रण अनुक्रम कुछ सामान्य पैटर्न का पालन करते हैं।
गिल्स

कृपया इस स्क्रिप्ट का उपयोग करने का तरीका प्रदान करें। क्या इसे पाइप इनपुट की आवश्यकता है? या स्थितिगत तर्क
ट्रेवर बॉयड स्मिथ

@TrevorBoydSmith या तो इनपुट के लिए काम करेगा, और आउटपुट हमेशा मानक आउटपुट पर होता है, जैसे कि विशिष्ट पाठ उपयोगिताओं।
गाइल्स

यह \ (\ xe2 \ x98 \ xba) जैसे मल्टीबाइट वर्णों का प्रबंधन करता है। [\ X80- \ x9f] खंड मध्य बाइट को स्ट्रिप्स करता है।
जेफरी

31

गाड़ी के रिटर्न को हटाने और पिछले पात्रों के बैकस्पेस-मिटाने के लिए गिल्स के उत्तर को अपडेट करना, जो साइगविन पर उत्पन्न एक टाइपस्क्रिप्ट के लिए मेरे लिए दोनों महत्वपूर्ण थे:

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

+1 मैं पहले से ही ओपी के रूप में एक ही प्रश्न टाइप कर रहा था जब मैं इस संदेश को आपकी स्क्रिप्ट और @Gilles के साथ पसंद करता था। आप दोनों के लिए +1
चमत्कार 173

10

मैं sedइस मामले में उपयोग करेंगे ।

करना:

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

sed -e "s / search / प्रतिस्थापित / g" मानक सामान है। रेगेक्स को नीचे दिया गया है:

\x1bकलर कोड \[से पहले एस्केप से मेल .\{1,5\}खाता है किसी भी एकल वर्ण के 1 से 5 तक पहले खुले ब्रैकेट से मेल खाता है। करने के लिए है \उन्हें mangling से खोल रखने के लिए घुंघराले ब्रेसिज़। mरेगेक्स में अंतिम चरित्र - आमतौर पर रंग कोड को ट्रेल करता है। //सब कुछ के साथ बदलने के लिए खाली स्ट्रिंग। gइसे प्रति पंक्ति कई बार मिलाएं।


3
यह रेगेक्स स्ट्रिप्स बहुत अधिक ( इसके बजाय foo\e[1m(1m = {बन जाता foo = {है foo(m = {), .द्वारा प्रतिस्थापित [0-9;]करना अधिक सटीक है।
लीकेनस्टीन

उस के .\{1,5\}साथ बदलें [^m]\{1,5\}- लेकिन यह भी ध्यान दें कि तब भी यह केवल "ग्राफिक्स रेंडरिंग" कोड (जो कि अंत में समाप्त होता है m) को हटाता है - मूल रूप से रंग, रिवर्स, बोल्ड और इटैलिक शैलियों (जहां लागू हो)।
हन्‍नू

यह नहीं निकालता है \x1b(B(जंग के रंग उत्पादन में शामिल)
ideasman42

1
ऐसा क्यों है \x1bऔर नहीं \033?
atripes

इसके \u001bबजाय हो सकता है\x1b
yunzen


6
# 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 उपयोग:

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

पर परीक्षण किया गया: - AIX 5.x / 6.1 / 7.1 - लिनक्स मैंड्रेक / मैंड्रिवा / SLES / फेडोरा - SunOS


3

मैंने scriptreplayएक स्क्रीन में चलाकर और स्क्रॉलबैक बफर को एक फ़ाइल में डंप करके समस्या को हल किया ।

निम्नलिखित उम्मीद की स्क्रिप्ट आपके लिए ऐसा करती है।

यह 250.000 लाइनों के साथ logfiles के लिए परीक्षण किया गया है। कामकाजी निर्देशिका में आपको अपने स्क्रिप्टलॉग की आवश्यकता होती है, 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

टाइम फ़ाइल जनरेट करने की कमांड कुछ मिनटों के लिए 100% CPU उपयोग उत्पन्न करती है और इसके समाप्त होने के बाद मेरी मेमोरी उपयोग 100% थी और रनिंग कमांड के परिणामस्वरूप "कांटा: मेमोरी आवंटित नहीं कर सकता"। और यह वास्तव में उम्मीद के मुताबिक काम नहीं किया।
barteks2x

टाइमिंग फ़ाइल जनरेट करने का एक आसान तरीका है। फ़ील्ड " delay blocksize" हैं, इसलिए कोई कारण नहीं है कि इसे केवल " 0 <entirefile>" न करें और बिना किसी देरी के पूरी चीज़ को डंप करें। आप ऐसा कर सकते हैं कि स्क्रिप्ट की साइज़ को घटाकर पहली लाइन ( tail -n +2 typescript|wc -c), और टाइमिंग फ़ाइल को बनाएं echo "0 "`tail -n +2 typescript|wc -c` > timing। यह मूल रूप से तत्काल scriptreplayहोगा , और पूरी स्क्रिप्ट को सबसे तेज गति से फिर से करेगा।
FeRD

1

इसी समस्या के समाधान की तलाश करते हुए यह प्रश्न मिला। थोड़ा और खुदाई और इस लिंक पर लाइव जर्नल में यह स्क्रिप्ट मिली। मैंने पूरी तरह से मेरे लिए काम किया। इस समस्या के बारे में और समाधान कैसे काम करता है, यह भी बहुत अच्छा है। निश्चित रूप से पढ़ने लायक। 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

मैं स्क्रिप्ट आउटपुट को सादे पाठ में परिवर्तित करने के लिए विशेष उपकरणों का उपयोग करना पसंद करूंगा, जो कि कस्टम रीजेक्सपी पर लगातार समर्थित और अच्छी तरह से परीक्षण किया जाता है। तो यह मेरे लिए काम किया:

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

स्क्रिप्ट कमांड टाइपस्क्रिप्ट फ़ाइल में कैप्चर करता है asi2txt - एसीसी कोड को एस्कॉर्ट्स जैसे कलरकोड्स, बैकस्पेस आदि के साथ रेग्युलर टेक्स्ट में कनवर्ट करता है, हालांकि मैंने पाया कि युगल अभी भी बच गए हैं। colb -bp - उन्हें पूरी तरह से हटा दिया।

मैंने इसे नवीनतम उबंटू डिस्को पर परीक्षण किया है, और यह काम करता है।


1

उबंटू ansi2txtमें colorized-logsपैकेज में एक कमांड है । यह एएनएसआई रंग कोड को अच्छी तरह से हटा देता है, लेकिन यह जगह पर पाठ को अधिलेखित करने के लिए उत्सर्जक ^Hया ^Mपात्रों द्वारा उत्पादित प्रगति सलाखों जैसी चीजों से नहीं निपटता है। उन लोगोंcol -b के साथ सौदा कर सकते हैं , इसलिए सर्वोत्तम परिणामों के लिए आप दोनों को जोड़ सकते हैं

cat typescript | ansi2txt | col -b

0

मैंने पाया कि टर्मिनल catके आउटपुट को देखने के लिए मुझे बस इस्तेमाल करने की ज़रूरत थी script। आउटपुट को किसी अन्य फ़ाइल पर रीडायरेक्ट करने पर यह मदद नहीं करता है, लेकिन परिणाम को पाठ संपादक के विपरीत cat -v, पढ़ने योग्य बनाता है col -b

रंगों को खत्म करने या परिणामों को फ़ाइल में सहेजने के लिए, आउटपुट को catटेक्स्ट एडिटर से या किसी अन्य catकमांड में आउटपुट कॉपी और पेस्ट करें , अर्थात:

cat > endResult << END
<paste_copied_text_here>
END

1
scriptओपी के मामले में आपके रन में कलर कोड के साथ आउटपुट शामिल था ?
जेफ स्कालर

catमूल रंगों को प्रस्तुत करना , जिसे मैनुअल कॉपी-एंड-पेस्ट द्वारा हटाया जा सकता है। ओपी ने उपयोग किया cat -vऔर col -b, दोनों एक सही-स्वरूपित अंतिम परिणाम के बजाय कोड प्रस्तुत करते हैं। मैंने अपना उत्तर संपादित कर दिया है।
रोजर ड्यूक

-2

अंतिम उत्तर पर जो tr और: cntrl का उपयोग करता है: हम शायद कर सकते हैं

sed "/^[[:cntrl:]]/d" output.txt

यह मेरे लिए काम करने लगता है क्योंकि vi द्वारा उत्पन्न सभी लाइनें एक नियंत्रण चरित्र से शुरू होती हैं। यह रिक्त रेखाओं और रेखाओं को भी अलग करने के लिए होता है जो एक टैब से शुरू होते हैं, हालांकि यह वह काम करता है जो मैं कर रहा हूं। हो सकता है कि \ n \ m \ t को छोड़कर किसी भी नियंत्रण वर्ण से मेल खाने का कोई तरीका हो।

हो सकता है कि हम विशेष नियंत्रण चरित्र की खोज कर सकते हैं, और यह vi द्वारा उत्पन्न सभी रद्दी लाइनों की तरह लग रहा है जो ^ जैसा दिखता है उसी के साथ शुरू होता है। हेक्सडम्प मुझे बताता है कि पहला चरित्र 1 बी है, इसलिए यह भी काम करता है

sed "/^\x1b/d" output.txt

यह ऊपर पोस्ट किए गए उत्तर के समान है, लेकिन यह ठीक से काम नहीं करता है क्योंकि कमांड चलाने के बाद, कुछ जंक चार्ट कमांड लाइन में पहले से ही जोड़ दिए जाते हैं जैसे कि उपयोगकर्ता ने उन्हें टाइप किया था।


1
कोई "अंतिम उत्तर" नहीं है क्योंकि उत्तर आदेश को बदल सकते हैं और कर सकते हैं। आपको उस उत्तर के नीचे "शेयर" बटन का उपयोग करना चाहिए जिसे आप संदर्भ देना चाहते हैं, और उसे अपने उत्तर में लिंक के रूप में शामिल करें। अपना उत्तर मान लेना एक टिप्पणी से कहीं अधिक होने के लिए पर्याप्त है, निश्चित रूप से। अभी मैं आपके द्वारा संदर्भित कई उत्तरों में से किसी को भी पहचान नहीं सकता।
रोइमा

1
"हम शायद कर सकता है ..." हाँ, हम कर सकता है कि - लेकिन यह होगा हटाना हर पंक्ति है कि शुरू होता है एक नियंत्रण चरित्र के साथ । के आउटपुट पर, उदाहरण के लिए, ls --color(जैसा कि प्रश्न में दिखाया गया है), आपका समाधान लगभग हर पंक्ति को हटा देगा जिसमें जानकारी है। अच्छा नही। लेकिन बेकार उपयोग को छोड़ने के लिए धन्यवाद cat। :
जी-मैन

वहाँ एक चरित्र वर्ग बनाने का एक तरीका है: iscntrl: लेकिन नहीं: isspace :? शायद कुछ सिंटेक्स जैसे ^ [[: iscntrl:] - [: isspace]]
स्नारन

-4

tr - वर्णों का अनुवाद या हटाना

cat typescript | tr -d [[:cntrl:]]

Unix Stackexchange में आपका स्वागत है! उत्तर देते समय कुछ स्पष्टीकरण देना बेहतर होगा क्योंकि आपका उत्तर कौन सा है।
स्टीफन राउच


3
यह वास्तव में सही ढंग से काम नहीं करेगा, क्योंकि यह 01;34mउदाहरण के लिए नहीं हटाएगा , और लाइन के अंत को हटा देगा newline (\n)
सोरोन्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.