tr บ่น“ ลำดับไบต์ที่ผิดกฎหมาย”


24

ฉันเป็นแบรนด์ใหม่สำหรับ UNIX และฉันใช้ "The Mac OS X Command Line" ของ Kirk McElhearn เพื่อสอนตัวเองด้วยคำสั่งบางอย่าง

ฉันพยายามใช้trและgrepเพื่อให้ฉันสามารถค้นหาสตริงข้อความในเอกสาร MS-Office Word ปกติ

$ tr '\r' '\n' < target-file | grep search-string

แต่ผลตอบแทนทั้งหมดคือ:

Illegal byte sequence.

robomechanoid:Position-Paper-Final-Draft robertjralph$ tr '\r' '\n' < Position-Paper-Final-Version.docx | grep DeCSS
tr: Illegal byte sequence
robomechanoid:Position-Paper-Final-Draft robertjralph$ 

ฉันใช้สคริปต์บรรทัดเดียวกับที่ฉันสร้างขึ้นviและทำการค้นหาอย่างถูกต้อง


ฉันไม่เห็นว่าทำไม tr จะบ่นคุณพิมพ์เหมือนที่คุณใส่ในคำถามหรือไม่ grep จะไม่พบสิ่งที่คุณต้องการ xdoc เป็นมาตรฐานที่กำหนดไว้ไม่ดี ไม่มีใครรู้ว่าไฟล์เหล่านั้นมีอะไรจริง ๆ ผู้คนได้ออกแบบวิศวกรรมย้อนกลับมาดูเหมือนว่ามาตรฐานไม่มีความช่วยเหลือ
ctrl-alt-delor

คำตอบ:


29

grepเป็นเครื่องมือประมวลผลข้อความ คาดว่าใส่ของพวกเขาจะเป็นไฟล์ข้อความ ดูเหมือนว่าสิ่งเดียวกันจะเกิดขึ้นtrบน macOS (แม้ว่าtrควรสนับสนุนไฟล์ไบนารี)

คอมพิวเตอร์เก็บข้อมูลเป็นลำดับของไบต์ ข้อความคือลำดับของอักขระ มีหลายวิธีที่ตัวละครเข้ารหัสเป็นไบต์เรียกว่าเข้ารหัสตัวอักษร พฤตินัยอักขระที่เป็นมาตรฐานการเข้ารหัสในส่วนของโลกโดยเฉพาะอย่างยิ่งใน OSX เป็นUTF-8ซึ่งเป็นเข้ารหัสสำหรับUnicodeชุดตัวอักษร มีเพียง 256 ไบต์ที่เป็นไปได้ แต่มีอักขระ Unicode มากกว่าล้านตัวดังนั้นอักขระส่วนใหญ่จึงเข้ารหัสเป็นหลายไบต์ UTF-8 เป็นการเข้ารหัสที่มีความยาวผันแปร: ขึ้นอยู่กับตัวอักษรซึ่งอาจใช้เวลาตั้งแต่หนึ่งถึงสี่ไบต์ในการเข้ารหัสอักขระ บางส่วนของไบต์ไม่ได้เป็นตัวแทนของตัวละครใน UTF-8 ดังนั้นจึงมีลำดับของไบต์ซึ่งไม่ใช่ไฟล์ข้อความ UTF-8 ที่ถูกต้อง

trกำลังบ่นเพราะมันพบกับลำดับไบต์ คาดว่าจะเห็นไฟล์ข้อความที่เข้ารหัสใน UTF-8 แต่จะเห็นข้อมูลไบนารีซึ่งไม่ถูกต้อง UTF-8

เอกสาร Microsoft Word ไม่ใช่ไฟล์ข้อความ: เป็นเอกสารประมวลผลคำ รูปแบบเอกสารการประมวลผลคำไม่เพียง แต่เข้ารหัสข้อความเท่านั้น แต่ยังจัดรูปแบบภาพที่ฝัง ฯลฯ รูปแบบ Word เช่นเดียวกับรูปแบบการประมวลผลคำส่วนใหญ่ไม่ใช่ไฟล์ข้อความ

คุณสามารถสั่งการประมวลผลข้อความเครื่องมือในการดำเนินการเกี่ยวกับไบต์โดยการเปลี่ยนสถานที่เกิดเหตุ เลือกโลแคล“ C” ซึ่งโดยทั่วไปหมายถึง“ ไม่มีอะไรแฟนซี” ในบรรทัดคำสั่งที่คุณสามารถเลือกการตั้งค่าสถานที่มีตัวแปรสภาพแวดล้อม

export LC_CTYPE=C
tr '\r' '\n' < target-file | grep search-string

สิ่งนี้จะไม่ส่งข้อผิดพลาดใด ๆ แต่จะไม่ทำสิ่งใดที่มีประโยชน์เนื่องจากtarget-fileยังคงเป็นไฟล์ไบนารีซึ่งไม่น่าจะมีสตริงการค้นหาส่วนใหญ่ที่คุณจะระบุ

อนึ่งtr '\r' '\n'ไม่ใช่คำสั่งที่มีประโยชน์มากเว้นแต่คุณจะมีไฟล์ข้อความเหลืออยู่จาก Mac OS 9 หรือเก่ากว่า \r(carriage return) เป็นตัวแบ่งบรรทัดใหม่ใน Mac OS ก่อน Mac OS X เนื่องจาก OSX ตัวคั่นบรรทัดใหม่คือ\n(ตัวป้อนบรรทัดมาตรฐาน unix) และไฟล์ข้อความไม่มีการขึ้นบรรทัดใหม่ Windows ใช้ลำดับสองอักขระ CR-LF เพื่อแสดงการขึ้นบรรทัดใหม่ tr -d '\r'จะแปลงไฟล์ข้อความ Windows เป็นไฟล์ข้อความ Unix / Linux / OSX

ดังนั้นคุณจะค้นหาเอกสาร Word จากบรรทัดคำสั่งได้อย่างไร .docxเอกสาร Word เป็นจริงไฟล์ zipที่มีไฟล์หลายคนหลักอยู่ในXML

unzip -l Position-Paper-Final-Version.docx

Mac OS X มีโปรแกรมอรรถประโยชน์zipgrepเพื่อค้นหาไฟล์ zip ภายใน

zipgrep DeCSS Position-Paper-Final-Version.docx

ผลลัพธ์จะไม่สามารถอ่านได้มากเนื่องจากไฟล์ XML ในรูปแบบ docx ส่วนใหญ่ประกอบด้วยบรรทัดขนาดใหญ่หนึ่งบรรทัด หากคุณต้องการค้นหาภายในเนื้อความหลักของเอกสารให้แตกไฟล์word/document.xmlจากไฟล์เก็บถาวร โปรดทราบว่านอกเหนือไปจากข้อความเอกสารไฟล์นี้มีมาร์กอัป XML ซึ่งแสดงถึงโครงสร้างของเอกสาร คุณสามารถนวดมาร์กอัป XML ได้ด้วยsedการแบ่งเป็นบรรทัดที่จัดการได้

unzip -p Position-Paper-Final-Version.docx word/document.xml |
sed -e 's/></>\n</g' |
grep DeCSS

1
+1 สำหรับการสรุปที่ดีและบิตเพิ่มเติม ฉันมีสิ่งหนึ่งที่จะพูดว่า ในการจัดรูปแบบ xml คุณสามารถใช้xml_ppมันในแพ็คเกจxml-twig-toolsบน Debian Gnu + Linux (ไม่ทราบว่ามี mac)
ctrl-alt-delor

2
Excel for Mac 2011 บันทึกไฟล์ CSV ด้วยการสิ้นสุดบรรทัด \ r ดังนั้นการเรียกใช้ tr นี้จึงมีความเกี่ยวข้องและเป็นประโยชน์
Noah Yetter

1
เช่นเดียวกับ Outlook สำหรับ Mac 2011 เมื่อคุณส่งออกรายชื่อผู้ติดต่อที่คั่นด้วยแท็บ
Ivan X

1
ฉันไม่มีชื่อเสียงเพียงพอที่จะลงคะแนนในที่นี้ แต่คำตอบนี้ไม่ถูกต้องที่สุด มันเริ่มต้นด้วย " tr[... ] คาดว่าอินพุตของพวกเขาจะเป็นไฟล์ข้อความ"; ในขณะที่ข้อมูลจำเพาะ POSIX ระบุอย่างชัดเจนว่า "อินพุตมาตรฐานสามารถเป็นไฟล์ประเภทใดก็ได้" . โปรดแก้ไขคำตอบของคุณ
7heo.tk

@ 7heo.tk“คำตอบนี้ไม่ถูกต้องอย่างเต็มที่” เป็น exageration ขั้นต้น แต่คุณกำลังขวา, trเป็นควรที่จะดำเนินการป้อนข้อมูลไบนารี (โดยเฉพาะที่มันควรจะ null กระบวนการไบต์ถูกต้อง) POSIX ไม่ได้ระบุอย่างชัดเจนว่าควรจัดการกับอินพุตอย่างไรซึ่งไม่ใช่ลำดับของอักขระ (ถ้าฉันเป็นผู้ดำเนินการฉันจะส่งลำดับไบต์ที่ไม่ถูกต้องผ่านการแก้ไข (หรือลบออกด้วย-s) และเพิ่มข้อบกพร่องกับคณะกรรมการมาตรฐาน) เห็นได้ชัดว่า macOS บ่นเกี่ยวกับพวกเขา
Gilles 'หยุดชั่วร้าย'

13

ฉันคิดว่าเสน่ห์ของคุณจากโลแคลคือ UTF-8 ดังนั้นคุณจะมีปัญหากับไฟล์ไบนารี เพียงเปลี่ยนเป็นโลแคล C:

LC_ALL=C tr '\r' '\n' < target-file | LC_ALL=C grep search-string

คุณสามารถใช้วงเล็บเพื่อหลีกเลี่ยงการระบุภาษาสองครั้ง LC_ALL=C ( tr '\r' '\n' < target-file | grep search-string ). อย่างไรก็ตาม docx ไม่ใช่ C local คือ utf16 และซิปและซับซ้อนและทุกคนเดา ฉันจะดูว่าการใช้เครื่องมือที่สามารถแปลงเป็นรูปแบบอื่นที่คุณสามารถประมวลผลเช่น html หรือ odt (odt ยังถูกซิปเช่นกัน แต่มีความชัดเจนและตีความได้ง่าย)
ctrl-alt-delor

1
ไวยากรณ์ที่มีวงเล็บ (วงเล็บ) ไม่ทำงานกับเชลล์ทั้งหมด (ไม่ใช่ทุบตี, ไม่ใช่ zsh, ไม่ใช่เส้นประ) จากนั้นที่เกี่ยวข้องกับไฟล์ MS Word นั้นขึ้นอยู่กับ ฉันมีไฟล์บางไฟล์ที่stringsคำสั่งให้ข้อความที่ชัดเจน
vinc17

หรือ( export LC_ALL=C; tr '\r' '\n' < target-file | grep search-string; )ควรทำงาน
vinc17

1
stringsมีพลังพิเศษ: สามารถอ่านไฟล์ที่ไม่ใช่แค่ utf-8 หรือ ascii text
ctrl-alt-delor

ขออภัยเกี่ยวกับ()สิ่งที่ฉันคิดว่าจะใช้งานได้ขอบคุณ @ vinc17 สำหรับการแก้ไข
ctrl-alt-delor
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.