Xóa ký tự điều khiển (bao gồm mã / màu bảng điều khiển) khỏi đầu ra tập lệnh


68

Tôi có thể sử dụng lệnh "script" để ghi lại một phiên tương tác tại dòng lệnh. Tuy nhiên, điều này bao gồm tất cả các ký tự điều khiển mã màu. Tôi có thể xóa các ký tự điều khiển (như backspace) bằng "col -b", nhưng tôi không thể tìm thấy một cách đơn giản để xóa mã màu.

Lưu ý rằng tôi muốn sử dụng dòng lệnh theo cách thông thường, vì vậy đừng muốn tắt màu ở đó - tôi chỉ muốn xóa chúng khỏi đầu ra tập lệnh. Ngoài ra, tôi biết có thể chơi xung quanh và thử tìm một regrec để sửa chữa mọi thứ, nhưng tôi hy vọng có một cách đơn giản hơn (và đáng tin cậy hơn - nếu có một mã tôi không biết khi tôi phát triển giải pháp regrec?).

Để hiển thị vấn đề:

spl62 tmp: tập lệnh
Script bắt đầu, file là typcript
spl62 lepl: ls
add-licence.sed build-example.sh commit-test push-docs.sh
add-licence.sh build.sh xóa-licence.sed setup.py
asn build-test.sh xóa-licence.sh src
build-doc.sh sạch doc-src test.ini
spl62 lepl: thoát
Script đã hoàn thành, file là typcript
spl62 tmp: bản thảo cat -v
Script bắt đầu vào ngày 09 tháng 6 năm 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: thoát ^ M

Kịch bản được thực hiện vào ngày 09 tháng 6 năm 2011 09:47:29 AM CLT
spl62 tmp: col -b <bản thảo 
Script bắt đầu vào ngày 09 tháng 6 năm 2011 09:47:27 AM 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: thoát

Kịch bản được thực hiện vào ngày 09 tháng 6 năm 2011 09:47:29 AM CLT

Câu trả lời:


57

Tập lệnh sau sẽ lọc ra tất cả các chuỗi điều khiển ANSI / VT100 / xterm cho (dựa trên ctlseqs ). Đã kiểm tra tối thiểu, vui lòng báo cáo bất kỳ trận đấu nào dưới hoặc quá khớp.

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

Các vấn đề đã biết:

  • Không phàn nàn về trình tự không đúng định dạng. Đó không phải là những gì kịch bản này là dành cho.
  • Đối số chuỗi nhiều dòng đến DCS / PM / APC / OSC không được hỗ trợ.
  • Byte trong phạm vi 128 Pha159 có thể được phân tích cú pháp dưới dạng ký tự điều khiển, mặc dù điều này hiếm khi được sử dụng. Đây là phiên bản phân tích các ký tự điều khiển không phải ASCII (điều này sẽ thu thập văn bản không phải ASCII trong một số mã hóa bao gồm 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;
}

nhờ cả hai câu trả lời. tôi cảm thấy tôi nên làm một cái gì đó như một câu trả lời tốt, mặc dù cả hai đều đưa ra biểu thức chính tả, điều mà tôi muốn tránh. đã chọn cái này vì nó đưa ra một tham chiếu cho định dạng.
rút cooke

@andrew: regrec của tôi đủ linh hoạt để tôi hy vọng nó hoạt động với hầu hết mọi thiết bị đầu cuối hiện có và có thể với bất kỳ thiết bị đầu cuối nào hiện tại. Tôi đã không kiểm tra nó nhiều, vì vậy có thể có lỗi, nhưng cách tiếp cận là âm thanh khi các chuỗi điều khiển tuân theo một vài mô hình chung.
Gilles

vui lòng cung cấp cách sử dụng tập lệnh này. Có yêu cầu đầu vào đường ống? hay lập luận vị trí?
Trevor Boyd Smith

@TrevorBoydSmith Hoặc sẽ hoạt động cho đầu vào và đầu ra luôn ở đầu ra tiêu chuẩn, giống như các tiện ích văn bản thông thường.
Gilles

Ký tự đa chuỗi mang này như ☺ (\ xe2 \ x98 \ xba). Mệnh đề [\ x80- \ x9f] tước byte giữa.
Jeffrey

31

Cập nhật câu trả lời của Gilles để loại bỏ trả lại vận chuyển và xóa lùi các ký tự trước đó, cả hai đều quan trọng đối với tôi đối với bản thảo được tạo trên 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;
}

+1 Tôi đã gõ một bài đăng với câu hỏi tương tự như OP khi tôi thích tin nhắn này với tập lệnh của bạn và của @Gilles. +1 cho cả hai bạn
miracle173

10

Tôi sẽ sử dụng sedtrong trường hợp này.

làm:

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

sed -e "s / search / thay thế / g" là công cụ tiêu chuẩn. regex được giải thích như sau:

\x1bkhớp với Thoát trước mã màu \[khớp với dấu ngoặc mở đầu tiên .\{1,5\}khớp từ 1 đến 5 của bất kỳ ký tự đơn nào. Phải \niềng răng xoăn để giữ cho vỏ khỏi xáo trộn chúng. mký tự cuối cùng trong regex - thường theo dõi mã màu. //chuỗi trống cho những gì để thay thế mọi thứ với. gphù hợp với nó nhiều lần trên mỗi dòng.


3
Regex này dải quá nhiều ( foo\e[1m(1m = {trở thành foo = {thay thế foo(m = {), thay thế .bằng [0-9;]là chính xác hơn.
Lekensteyn

Thay thế .\{1,5\}bằng [^m]\{1,5\}điều đó - nhưng cũng lưu ý rằng điều này ngay cả khi đó vẫn chỉ xóa các mã "biểu hiện đồ họa" (những mã kết thúc bằng một m) - về cơ bản là các kiểu màu, ngược, đậm và in nghiêng (nếu có).
Hannu

Điều này không loại bỏ \x1b(B(bao gồm trong đầu ra màu rỉ sét)
ideaman42

1
Tại sao lại \x1bnhư \033vậy?
atripes

Nó có thể \u001bthay vì\x1b
yunzen

9
cat typescript | perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' | col -b > typescript-processed

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

=> cách sử dụng:

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

đã thử nghiệm trên: - AIX 5.x / 6.1 / 7.1 - Linux Mandrake / Mandriva / SLES / Fedora - SunOS


3

Tôi đã giải quyết vấn đề bằng cách chạy scriptreplaytrong màn hình và kết xuất bộ đệm cuộn lại thành tập tin.

Các kịch bản mong đợi sau đây làm điều này cho bạn.

Nó đã được thử nghiệm cho logfiles với tối đa 250.000 dòng. Trong thư mục làm việc, bạn cần scriptlog của mình, một tệp có tên là "thời gian" với 10.000.000 lần dòng "1 10" trong đó và tập lệnh. Tôi cần tên scriptfile của bạn làm đối số dòng lệnh, như thế nào ./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

Các tập tin thời gian có thể được tạo ra bởi

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

Lệnh tạo tệp thời gian đã tạo ra mức sử dụng CPU 100% trong vài phút và sau khi hoàn thành việc sử dụng bộ nhớ của tôi là 100% và lệnh chạy dẫn đến "fork: không thể phân bổ bộ nhớ". Và nó không thực sự hoạt động như mong đợi.
barteks2x

Có một cách dễ dàng hơn nhiều để tạo tập tin thời gian. Các trường là " delay blocksize", vì vậy không có lý do gì để không tạo ra nó " 0 <entirefile>" và đổ toàn bộ mọi thứ không chậm trễ. Bạn có thể làm điều đó bằng cách lấy kích thước của tập lệnh trừ đi dòng đầu tiên ( tail -n +2 typescript|wc -c) và tạo tệp thời gian bằng echo "0 "`tail -n +2 typescript|wc -c` > timing. Điều đó về cơ bản là ngay lập tức và scriptreplaysẽ phát lại toàn bộ tập lệnh với tốc độ nhanh nhất có thể.
FeRD

1

Tìm thấy câu hỏi này trong khi tìm kiếm một giải pháp cho cùng một vấn đề. Đào sâu hơn một chút và tìm thấy kịch bản này tại Live Journal tại liên kết này. Tôi đã làm việc hoàn hảo cho tôi. Đây cũng là một bài viết rất hay về vấn đề này và cách giải pháp hoạt động. Chắc chắn giá trị đọc. 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

Tôi muốn sử dụng các công cụ chuyên dụng để chuyển đổi đầu ra tập lệnh thành văn bản thuần túy, được liên tục hỗ trợ và thử nghiệm tốt, qua chế độ regrec tùy chỉnh. Vì vậy, điều này đã làm việc cho tôi:

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

lệnh script bắt vào tập tin bản thảo ansi2txt - chuyển đổi mã ansi với các lối thoát như mã màu, không gian ngược, v.v. thành văn bản thông thường, tuy nhiên tôi thấy rằng cặp vợ chồng vẫn thoát. col -bp - loại bỏ chúng hoàn toàn.

Tôi đã thử nghiệm điều này trên sàn nhảy Ubuntu mới nhất và nó hoạt động.


1

Có một ansi2txtlệnh trong colorized-logsgói trên Ubuntu. Nó loại bỏ mã màu ANSI độc đáo, nhưng nó không xử lý những thứ như thanh tiến trình được tạo ra bằng cách phát ra ^Hhoặc ^Mký tự để ghi đè lên văn bản tại chỗ. col -bcó thể đối phó với những điều đó , vì vậy để có kết quả tốt nhất, bạn có thể kết hợp cả hai

cat typescript | ansi2txt | col -b

0

Tôi thấy rằng chỉ cần sử dụng catlà tất cả những gì tôi cần để xem đầu ra của scriptthiết bị đầu cuối. Điều này không giúp ích khi chuyển hướng đầu ra sang một tệp khác, nhưng làm cho kết quả có thể đọc được, không giống như cat -v,col -b hoặc một trình soạn thảo văn bản.

Để loại bỏ màu sắc hoặc lưu kết quả vào một tệp, sao chép thủ công và dán đầu ra từ catvào trình soạn thảo văn bản hoặc vào một catlệnh khác , nghĩa là:

cat > endResult << END
<paste_copied_text_here>
END

1
scriptchạy của bạn có bao gồm đầu ra với mã màu được đính kèm, như trong trường hợp của OP không?
Jeff Schaller

Sử dụng cattrình bày các màu gốc, có thể được loại bỏ bằng cách sao chép và dán thủ công. OP đã sử dụng cat -vcol -b, cả hai đều trình bày mã chứ không phải là kết quả cuối cùng được định dạng đúng. Tôi đã chỉnh sửa câu trả lời của tôi.
Roger Dueck

-2

Theo dõi câu trả lời cuối cùng sử dụng tr và: cntrl: chúng ta có thể làm gì không

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

Điều này có vẻ hiệu quả với tôi vì tất cả các dòng được tạo bởi vi bắt đầu bằng ký tự điều khiển. Nó cũng xảy ra để loại bỏ các dòng và dòng trống bắt đầu bằng một tab, mặc dù nó hoạt động cho những gì tôi đang làm. Có thể có một cách để khớp với bất kỳ ký tự điều khiển nào ngoại trừ \ n \ m \ t.

Có lẽ chúng ta có thể tìm kiếm ký tự điều khiển cụ thể và có vẻ như tất cả các dòng rác được tạo bởi vi bắt đầu với giao diện ^ [. hexdump cho tôi biết ký tự đầu tiên là 1b, vì vậy điều này dường như cũng hoạt động

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

Điều này trông giống như một câu trả lời được đăng ở trên, nhưng nó không hoạt động đúng bởi vì sau khi chạy lệnh, một số ký tự rác đã được thêm vào dòng lệnh như thể người dùng đã gõ chúng.


1
Không có "câu trả lời cuối cùng" như câu trả lời có thể và thay đổi thứ tự. Bạn nên sử dụng nút "chia sẻ" bên dưới câu trả lời bạn muốn tham khảo và đưa nó vào như một liên kết trong câu trả lời của bạn. Tất nhiên, giả sử câu trả lời của bạn là đủ để có nhiều hơn một nhận xét, tất nhiên. Ngay bây giờ tôi không thể xác định câu trả lời nào trong số các câu trả lời bạn đang tham khảo.
roaima

1
“Chúng ta có thể có thể làm ...” Vâng, chúng tôi có thể làm điều đó - nhưng nó sẽ xóa tất cả các dòngbắt đầu với một ký tự điều khiển . Ví dụ, ở đầu ra của ls --color(như trong câu hỏi), giải pháp của bạn sẽ xóa hầu hết mọi dòng có chứa thông tin. Không tốt. Nhưng cảm ơn vì đã bỏ đi việc sử dụng vô ích cat. :-)
G-Man

Có cách nào để tạo một lớp ký tự đó là: iscntrl: but not: isspace:? Có thể một số cú pháp như ^ [[: iscntrl:] - [: isspace]]
snaran

-4

tr - dịch hoặc xóa ký tự

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

Chào mừng bạn đến với Unix Stackexchange! Khi đưa ra câu trả lời, tốt nhất là đưa ra một số lời giải thích về lý do TẠI SAO câu trả lời của bạncâu trả lời .
Stephen Rauch


3
Điều này thực sự sẽ không hoạt động chính xác, vì nó sẽ không loại bỏ một 01;34mví dụ, và sẽ loại bỏ cuối dòng newline (\n).
sorontar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.