tr phàn nàn về chuỗi byte bất hợp pháp


24

Tôi hoàn toàn mới với UNIX và tôi đang sử dụng "Dòng lệnh Mac OS X" của Kirk McElhearn để dạy cho bản thân một số lệnh.

Tôi đang cố gắng sử dụng trgrepđể tôi có thể tìm kiếm các chuỗi văn bản trong Tài liệu Word MS-Office thông thường.

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

Nhưng tất cả những gì nó trả về là:

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$ 

Tôi thực sự đã chạy cùng một dòng trên một tập lệnh mà tôi đã tạo vivà nó thực hiện tìm kiếm chính xác.


Tôi không thể hiểu tại sao tr sẽ phàn nàn, bạn có gõ giống như bạn đặt câu hỏi không? grep sẽ không tìm thấy những gì bạn muốn, xdoc là một tiêu chuẩn không xác định. Không ai thực sự biết những gì trên các tập tin đó, mọi người đã thiết kế ngược lại, rõ ràng tiêu chuẩn là không có ích.
ctrl-alt-delor

Câu trả lời:


29

greplà một công cụ xử lý văn bản. Nó hy vọng đầu vào của họ là tập tin văn bản . Có vẻ như điều tương tự cũng xảy ra với trmacOS (mặc dù trđược cho là hỗ trợ các tệp nhị phân).

Máy tính lưu trữ dữ liệu dưới dạng chuỗi byte . Một văn bản là một chuỗi các ký tự. Có một số cách để mã hóa các ký tự dưới dạng byte, được gọi là mã hóa ký tự . Mã hóa ký tự chuẩn trên thực tế ở hầu hết các nơi trên thế giới, đặc biệt là trên OSX, là UTF-8 , là mã hóa cho bộ tự Unicode . Chỉ có 256 byte có thể, nhưng hơn một triệu ký tự Unicode có thể, vì vậy hầu hết các ký tự được mã hóa thành nhiều byte. UTF-8 là một mã hóa có độ dài thay đổi: tùy thuộc vào ký tự, nó có thể mất từ ​​một đến bốn byte để mã hóa một ký tự. Một số chuỗi byte không đại diện cho bất kỳ ký tự nào trong UTF-8. Do đó, có các chuỗi byte không phải là tệp văn bản UTF-8 hợp lệ.

trđang phàn nàn vì nó gặp phải một chuỗi byte như vậy. Nó hy vọng sẽ thấy một tệp văn bản được mã hóa trong UTF-8, nhưng nó thấy dữ liệu nhị phân không hợp lệ UTF-8.

Tài liệu Microsoft Word không phải là tệp văn bản: đó là tài liệu xử lý văn bản. Các định dạng tài liệu xử lý văn bản không chỉ mã hóa văn bản mà còn định dạng, hình ảnh nhúng, v.v ... Định dạng Word, giống như hầu hết các định dạng xử lý văn bản, không phải là một tệp văn bản.

Bạn có thể hướng dẫn các công cụ xử lý văn bản hoạt động trên byte bằng cách thay đổi ngôn ngữ . Cụ thể, chọn miền địa phương của C C, có nghĩa là về cơ bản có nghĩa là không có gì lạ mắt. Trên dòng lệnh, bạn có thể chọn cài đặt ngôn ngữ với các biến môi trường .

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

Điều này sẽ không phát ra bất kỳ lỗi nào, nhưng nó sẽ không làm gì hữu ích vì target-fileđây vẫn là một tệp nhị phân không có khả năng chứa hầu hết các chuỗi tìm kiếm mà bạn sẽ chỉ định.

Ngẫu nhiên, tr '\r' '\n'không phải là một lệnh rất hữu ích trừ khi bạn có các tệp văn bản còn sót lại từ Mac OS 9 trở lên. \r(trả về vận chuyển) là dấu tách dòng mới trong Mac OS trước Mac OS X. Kể từ OSX, dấu tách dòng mới là \n(nguồn cấp dữ liệu, tiêu chuẩn unix) và tệp văn bản không chứa trả về vận chuyển. Windows sử dụng chuỗi hai ký tự CR-LF để thể hiện các ngắt dòng; tr -d '\r'sẽ chuyển đổi tệp văn bản Windows thành tệp văn bản Unix / Linux / OSX.

Vậy làm thế nào bạn có thể tìm kiếm trong một tài liệu Word từ dòng lệnh? Một .docxtài liệu Word thực sự là một kho lưu trữ zip chứa nhiều file, những cái chính là trong XML .

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

Mac OS X bao gồm tiện ích zipgrep để tìm kiếm bên trong các tệp zip.

zipgrep DeCSS Position-Paper-Final-Version.docx

Kết quả sẽ không dễ đọc vì các tệp XML ở định dạng docx chủ yếu bao gồm một dòng lớn. Nếu bạn muốn tìm kiếm bên trong văn bản chính của tài liệu, hãy giải nén tệp word/document.xmltừ kho lưu trữ. Lưu ý rằng ngoài văn bản tài liệu, tệp này chứa đánh dấu XML đại diện cho cấu trúc của tài liệu. Bạn có thể xoa bóp đánh dấu XML một chút sedđể chia nó thành các dòng có thể quản lý được.

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

1
+1 để tóm tắt tốt và thêm bit. Tôi có một điều để nói mặc dù. Để định dạng xml, bạn có thể sử dụng xml_ppnó trong gói xml-twig-toolstrên Debian Gnu + Linux (không biết máy mac).
ctrl-alt-delor

2
Excel cho Mac 2011 lưu các tệp CSV với kết thúc dòng \ r vì vậy việc gọi tr này trên thực tế khá phù hợp và hữu ích.

1
Cũng như Outlook cho Mac 2011 khi bạn xuất danh sách liên hệ được phân tách bằng tab.
Ivan X

1
Chà, tôi không đủ danh tiếng để đánh giá thấp điều này, nhưng câu trả lời này hoàn toàn không đúng. Nó bắt đầu bằng " tr[...] hy vọng đầu vào của chúng là tệp văn bản."; trong khi đặc tả POSIX ghi rõ "Đầu vào tiêu chuẩn có thể là bất kỳ loại tệp nào." . Hãy sửa câu trả lời của bạn.
7heo.tk

@ 7heo.tk “câu trả lời này là hoàn toàn không chính xác” là một exageration gộp, nhưng bạn nói đúng, trđược cho là để xử lý đầu vào nhị phân (đặc biệt, đó là nghĩa vụ cho quá trình rỗng byte chính xác). POSIX không xác định rõ ràng cách thức xử lý đầu vào không phải là một chuỗi ký tự. (Nếu tôi là người triển khai, tôi sẽ chuyển các chuỗi byte không hợp lệ thông qua việc không sửa đổi (hoặc loại bỏ chúng bằng -s) đưa ra một khiếm khuyết với ủy ban tiêu chuẩn.) Rõ ràng, tr của macOS phàn nàn về chúng.
Gilles 'SO- ngừng trở nên xấu xa'

13

Tôi cho rằng bùa chú của bạn từ các địa phương là UTF-8, do đó bạn sẽ gặp vấn đề trên các tệp nhị phân. Chỉ cần chuyển sang ngôn ngữ C:

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

bạn có thể sử dụng dấu ngoặc để tránh chỉ định ngôn ngữ hai lần. LC_ALL=C ( tr '\r' '\n' < target-file | grep search-string ). Tuy nhiên, docx không phải là C cục bộ. Là utf16 và nén và phức tạp và đoán của bất cứ ai. Tôi sẽ xem như sử dụng một công cụ có thể chuyển đổi nó sang một định dạng khác mà bạn có thể xử lý, ví dụ như html hoặc odt (odt cũng được nén, nhưng được xác định rõ và dễ hiểu).
ctrl-alt-delor

1
Cú pháp với dấu ngoặc (dấu ngoặc đơn) không hoạt động với tất cả các shell (không bash, không zsh, không dash). Sau đó, liên quan đến tệp MS Word, nó phụ thuộc. Tôi có một số tập tin như vậy trong đó stringslệnh cho văn bản rõ ràng.
vinc17

Ngoài ra, ( export LC_ALL=C; tr '\r' '\n' < target-file | grep search-string; )nên làm việc.
vinc17

1
stringscó siêu năng lực: nó có thể đọc các tệp không chỉ là văn bản utf-8 hoặc ascii.
ctrl-alt-delor

Xin lỗi về ()điều tôi nghĩ rằng nó sẽ hoạt động, cảm ơn @ vinc17 đã sửa chữa.
ctrl-alt-delor
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.