วิธีล้างข้อมูลเอาต์พุตของคำสั่ง linux 'script'


35

ฉันใช้คำสั่ง 'สคริปต์' ของ linux http://www.linuxcommand.org/man_pages/script1.htmlเพื่อติดตามเซสชันแบบโต้ตอบ ไฟล์เอาต์พุตจากนั้นมีอักขระที่ไม่สามารถพิมพ์ได้รวมถึงการกดแป้น Backspace ของฉัน

มีวิธีจัดระเบียบไฟล์เอาต์พุตเหล่านี้ให้เป็นระเบียบเพื่อให้มีเฉพาะสิ่งที่แสดงบนหน้าจอหรือไม่

หรือมีวิธีอื่นในการบันทึกเซสชันเชลล์แบบโต้ตอบ (อินพุทและเอาท์พุท)?


"หรือมีวิธีบันทึกเซสชันเชลล์เชิงโต้ตอบ (อินพุตและเอาต์พุต) อีกวิธีหนึ่งหรือไม่" คุณรู้จักasciinema.orgหรือไม่
masterxilo

คำตอบ:


34

หากคุณต้องการดูไฟล์จากนั้นคุณสามารถส่งออกผ่านcol -bp; นี่ตีความอักขระควบคุม จากนั้นคุณสามารถผ่านท่อได้น้อยลงหากคุณต้องการ

col -bp typescript | less -R

ในบางระบบcolจะไม่ยอมรับอาร์กิวเมนต์ชื่อไฟล์ให้ใช้ไวยากรณ์นี้แทน:

col -bp <typescript | less -R

1
ในระบบของฉันcolจะไม่ยอมรับชื่อไฟล์ดังนั้นฉันจึงcol -bp < typescript ได้รับสิ่งที่ฉันต้องการ
Andrew

ใช้งานไม่ได้สำหรับฉันกวนสัญญาณบางส่วน
อเล็กซ์

1
ในระบบของฉันless -Rด้วยตัวเองให้ผลผลิตที่ดีกว่าการวางท่อผ่านcol -bpก่อน
Brian Hawkins

@ BrianHawkins ฉันเห็นด้วย การใช้col -bp <typescript | less -Rไม่แสดงคอนโซล colorized การใช้less -R typescriptจะแสดงคอนโซล colorized!
เทรเวอร์บอยด์สมิ ธ

นี้เป็นสิ่งที่ดี lessแต่ถ้าคุณต้องการดูสคริปต์ในการโต้ตอบ
Trevor Boyd Smith

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

นี่คือการตีความบางส่วนของอินพุตสตริงไปที่perl:

  • s/pattern//gหมายถึงการทำการทดแทนในทั้งหมด ( gตัวเลือกหมายถึงทำทุกอย่างแทนการหยุดแทนแรก) สตริงการป้อน

นี่คือการตีความรูปแบบ regex บางส่วน:

  • \e ตรงกับอักขระควบคุมพิเศษ "escape" (ASCII 0x1A)
  • (และ)เป็นจุดเริ่มต้นและจุดสิ้นสุดของกลุ่ม
  • |หมายความว่ากลุ่มสามารถจับคู่หนึ่งในรูปแบบ N ตำแหน่งที่ N pattern อยู่ที่ไหน
    • [^\[\]] หรือ
    • \[.*?[a-zA-Z] หรือ
    • \].*?\a
  • [^\[\]] วิธี
    • ตรงกับชุดของอักขระ NOT ที่ไม่มีอักขระ[และ]
  • \[.*?[a-zA-Z] วิธี
    • จับคู่สตริงที่ขึ้นต้นด้วย[แล้วทำแบบไม่โลภ.*?จนตัวอักษรตัวแรก
  • \].*?\a วิธี
    • จับคู่สตริงที่ขึ้นต้นด้วย]แล้วทำแบบไม่โลภ.*?จนกระทั่งคุณกดตัวควบคุมพิเศษที่เรียกว่า "ตัวเตือน (เบล) ตัวอักษร"

1
ฉันยังคงต้องคิดหาวิธี แต่มันใช้งานได้จริง;)
asdmin

@asdmin - โดยทั่วไปแล้วสิ่งนี้จะสะท้อนเอาท์พุทของtypescriptไปยังperlโปรแกรมที่ลบอักขระควบคุมบางตัวออกจากเอาต์พุตจากนั้นไพพ์เอาต์พุตไปยังcolคำสั่งunix ซึ่ง-bตัวเลือกจะลบส่วนสำคัญ "ลบ" ในการถอดเสียง จากนั้นไพพ์เอาต์พุตไปยังไฟล์ข้อความ
Peter Nore

นี่กวนสัญญาณออกในบรรทัดแรกของ typescript สำหรับฉัน แต่เป็นคำตอบที่ดีที่สุด
อเล็กซ์

ดูเหมือนว่าจะทำงานได้ดีกับบางตัวพิมพ์ สามารถอ่านได้ง่ายกว่าเอาต์พุตที่ผลิตโดยคำตอบที่ยอมรับได้
fakedad

คำตอบในตำนาน!
แซค

2

สำหรับscriptผลผลิตจำนวนมากฉันจะแฮกสคริปต์ perl พร้อม ๆ กัน มิฉะนั้นแก้ไขด้วยตัวแก้ไขที่ดี

ไม่น่าจะเป็นวิธีอัตโนมัติที่มีอยู่ในการลบตัวควบคุมscriptออกจากเอาต์พุตในแบบที่ทำซ้ำสิ่งที่แสดงบนหน้าจอในช่วงเวลาที่สำคัญบางอย่าง (เช่นเมื่อโฮสต์กำลังรออักขระแรกของอินพุตผู้ใช้บางคน)

ตัวอย่างเช่นหน้าจออาจว่างเปล่ายกเว้นAndrew $ถ้าคุณพิมพ์rm /*และกด backspace สิบสองครั้ง (มากกว่าที่จำเป็น) สิ่งที่แสดงบนหน้าจอในตอนท้ายนั้นขึ้นอยู่กับว่าเชลล์กำลังทำงานอยู่sttyการตั้งค่าปัจจุบันของคุณคืออะไร ( ซึ่งคุณอาจเปลี่ยนบางส่วนผ่านเซสชัน) และปัจจัยอื่น ๆ ด้วย

ข้างต้นนำไปใช้กับวิธีอัตโนมัติใด ๆ ของการจับอินพุทและเอาท์พุทอย่างต่อเนื่อง ทางเลือกหลักคือการ "จับภาพหน้าจอ" หรือตัดและวางหน้าจอตามเวลาที่เหมาะสมในระหว่างเซสชัน (ซึ่งเป็นสิ่งที่ฉันทำสำหรับคำแนะนำผู้ใช้บันทึกสำหรับบันทึกประจำวัน ฯลฯ )


2

คำตอบในส่วนที่สองของคำถามของฉันคือการใช้เครื่องมืออำนวยความสะดวกในการบันทึกในหน้าจอ gnu: ^A Hจากภายในเซสชันหน้าจอที่ทำงานอยู่ เอกสารประกอบอยู่ที่http://www.gnu.org/software/screen/manual/screen.html#Logging


2

ฉันใช้cat filenameซึ่งจะลบอักขระควบคุม :-)


imo นี่เป็นคำตอบที่ดีกว่าเพราะมันจะลบอักขระควบคุมทั้งหมดออกไป
Nathanael Farley

บน OSX แมวจะไม่ลบอักขระควบคุมสี ...
Nick

9
ที่จริงแล้ว cat ไม่ได้ลบตัวควบคุมออกเลย แต่จะเอาท์พุทเป็นคำต่อคำและจากนั้นเทอร์มินัลก็จะตีความมัน ซึ่งอาจเหมาะกับคุณถ้า typescript ของคุณสั้นเมื่อเทียบกับเทอร์มินัลบัฟเฟอร์ของคุณและคุณสามารถคัดลอกและวางจากเทอร์มินัลได้ ไม่ดีนักหากตัวพิมพ์ของคุณมีขนาดใหญ่
mc0e

1
ตกลง สิ่งนี้จะไม่ลบอะไรเลย มันยอมให้เชลล์ตีความมัน พวกเขายังคงอยู่
Kentgrav

2

หากสิ่งที่คุณต้องการคือการบันทึกคำสั่งของคุณ (เช่นเปลี่ยนพวกเขาเป็นสคริปต์ทุบตีในภายหลัง) การแฮ็คที่เหมาะสมก็คือการทำงานscript(1)จากนั้นก็ดำเนินการภายใน

bash -x

หลังจากนั้นgrepไฟล์เอาต์พุต (โดยปกติคือ "typescript") มองหาบรรทัดที่ขึ้นต้นด้วย "+" การแสดงออกปกติ^\+จะทำเคล็ดลับ


2

หากคุณต้องการเขียนผลลัพธ์ไปยังไฟล์:

col -bp < typescript >>newfile

ใช้คำสั่ง unix2dos เพื่อแปลงไฟล์เป็นรูปแบบ Windows หากคุณต้องการ


1
บน Ubuntu 14.04 นั้นทิ้งขยะจำนวนมากไว้ที่จุดเริ่มต้นและจุดสิ้นสุด ค่อนข้างอ่านได้ แต่ไม่ค่อยสะอาด
mc0e

2

col -bp ประมวลผลแบ็คสเปซตามต้องการ (AFAIK) แต่มันก็ทำให้ลำดับการหลบหนีของสีเปลี่ยนไป มันอาจเป็นการดีที่จะลบลำดับสีออกก่อนจากนั้นประมวลผลแบ็กสเปซถ้าเป็นไปได้

นี่เป็นความต้องการที่พบบ่อยมากและฉันประหลาดใจที่ไม่มีวิธีแก้ปัญหามากขึ้น มันเป็นเรื่องธรรมดามากที่จะเขียนสคริปต์เซสชันจากนั้นมีคนต้องการตรวจสอบขั้นตอน คุณต้องการตัดข้อผิดพลาดการพิมพ์เล็กน้อยทั้งหมดและลำดับการหลีกสีเพื่อสร้างสคริปต์ "ใหม่ทั้งหมด" ของขั้นตอนสำหรับการอ้างอิงในอนาคต ต้องการข้อความ ASCII แบบง่าย ฉันคิดว่านี่เป็นสิ่งที่ "มนุษย์อ่านได้" และมันเป็นสิ่งที่สมเหตุสมผลที่จะทำ


1

ฉันพบคำตอบที่ dewtall ให้กับคำถามที่คล้ายกันบนกระดาน Unix เพื่อให้มีประสิทธิภาพมากขึ้นในการลบอักขระควบคุมออกจากสคริปต์หากคุณอยู่ในสภาพแวดล้อมที่ Perl พร้อมให้คุณใช้งาน

สคริปต์ของ dewtall:

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

ในการลบอักขระควบคุม:

./dewtalls-script.pl < output-from-script-that-needs-control-characters-removed


0

ฉันพบวิธีที่ดีที่จะทำ ในระบบของฉันบรรทัดเอาท์พุทที่ยาวจะถูกโรยด้วย "^ M" (พื้นที่ว่างตามด้วย carriage return) "^ M" สามารถถูกแทนที่อย่างดีด้วยอักขระโมฆะ "^ @" ซึ่งไม่แสดงเลยเมื่อคุณ cat ไฟล์

ฉันจับเวลาด้วยดังนั้นเพื่อที่จะเล่นไฟล์ซ้ำได้อย่างสมบูรณ์แบบฉันไม่สามารถลบ "^ M" ได้อย่างสมบูรณ์โดยใช้คำสั่งด้านล่าง (เพราะ scriptreplay นับจำนวนไบต์):

tr '\r' '\0' | sed 's/ \x0//g'

ฉันเรียกใช้คำสั่งสคริปต์ของฉันเช่นนี้:

script -t -f session.log 2>timing

ดังนั้นสิ่งที่ฉันทำภายหลังคือ:

cat session.log | tr '\r' '\0' > typescript 
scriptreplay -t timing | sed 's/ \x0//g'

การแก้ไขครั้งแรก (ก่อนเล่นซ้ำ) จะรักษาจำนวนไบต์ในไฟล์ การแก้ไขครั้งที่สอง (หลังจากเล่นซ้ำ) จะกำจัดพื้นที่สีขาวในที่สุ่ม (โปรดทราบว่าโดยค่าเริ่มต้น scriptreplay ค้นหาไฟล์อินพุตชื่อ "typescript" ซึ่งเป็นเหตุผลที่ฉันไม่ได้ให้มันหลังจาก "เวลา")



-1

อีกวิธีหนึ่งคือการใช้stringsซึ่งพิมพ์เฉพาะอักขระที่พิมพ์ได้จากไฟล์ (หรือจากอินพุตมาตรฐาน):

strings -n 1 filename

-n 1ชุดตัวเลือกความยาวต่ำสุดของลำดับที่จะได้รับการเก็บรักษาไว้ให้เป็นหนึ่งจึงทำให้ตัวอักษรพิมพ์แน่ใจว่าแม้แต่คนเดียวล้อมรอบด้วยอักขระที่ไม่ใช่พิมพ์จะถูกเก็บไว้

ข้อเสียข้อหนึ่งที่เป็นไปได้ของวิธีนี้คือการstringsเพิ่มตัวแบ่งบรรทัดระหว่างสตริงที่ต่อเนื่องกันของตัวอักษรที่พิมพ์ได้ ตัวอย่างเช่นไฟล์ที่มีเนื้อหา

Foo<SOMECONTROLCHAR>Bar

(ที่<SOMECONTROLCHAR>เป็นตัวควบคุมหรือตัวละครที่ไม่สามารถพิมพ์ได้อื่น ๆ ) จะถูกส่งกลับเป็น

Foo
Bar

ปัญหาอื่นที่เกิดขึ้นในความคิดเห็นคือลำดับของอักขระควบคุมประกอบด้วยการรวมกันของอักขระที่พิมพ์ได้และไม่สามารถพิมพ์ได้และวิธีการนี้จะลบส่วนหนึ่งของเหล่านั้นออกเท่านั้น

อย่างไรก็ตามstringsทำได้ดีในการลบอักขระควบคุมเช่น backspace ที่กล่าวถึงในคำถาม


stringsไม่ได้ลบอักขระที่ไม่สามารถพิมพ์ได้ทั้งหมด มันระบุและพิมพ์ลำดับของตัวละครที่พิมพ์ได้ นั่นไม่ใช่สิ่งเดียวกัน
CVn

@ MichaelKjörlingคุณพูดถูกโดยค่าเริ่มต้นstringsจะพิมพ์เฉพาะลำดับความยาวต่ำสุดที่ 4 ฉันได้แก้ไขคำตอบของฉันโดยเพิ่ม-n 1ตัวเลือกที่กำหนดความยาวต่ำสุดไว้ที่ 1 ขอบคุณที่ชี้ให้เห็น
justfortherec

คำตอบยังคงอ้างสิทธิ์เดิมที่stringsลบอักขระที่ไม่สามารถพิมพ์ได้ทั้งหมดออกดังนั้นจึงยังคงผิดพลาดในลักษณะเดียวกับก่อนการแก้ไข มันก็แตกหักเพราะ "รหัสสีบางส่วน" (และรหัสควบคุมโดยทั่วไป) มักประกอบด้วยอักขระที่พิมพ์ได้และไม่สามารถพิมพ์ได้ ตัวอย่างเช่นลำดับรหัสควบคุมเพื่อเปลี่ยนสีข้อความอาจอยู่ในESC[01;52mตำแหน่งที่ESCเป็นอักขระ escape ตัวเดียว (ค่าไบต์ 27) ใช้stringsตามที่คุณแนะนำจะทิ้งไว้[01;52mในเอาต์พุตซึ่งไม่มีความหมาย
CVn

จุดดี @ MichaelKjörling โดยเฉพาะอย่างยิ่งตัวอย่างที่มีรหัสสีเป็นเรื่องที่โชคร้ายมาก ขอบคุณที่ช่วยฉันปรับปรุงคำตอบของฉัน การแก้ไขตอบข้อกังวลของคุณอย่างเหมาะสมหรือไม่? stringsอาจไม่ทำงานเหมือนกับคำตอบอื่น ๆ แต่ IMHO เป็นแนวทางที่ถูกต้องในการแก้ปัญหาที่อธิบายไว้ในคำถาม
justfortherec
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.