tr narzeka na „nielegalną sekwencję bajtów”


24

Jestem zupełnie nowy w systemie UNIX i używam „Linii poleceń Mac OS X” Kirka McElhearna, aby nauczyć się kilku poleceń.

Ja próbuje użyć tri greptak, że mogę szukać ciągów tekstowych w regularnych MS-Office Word dokument.

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

Ale wszystko, co zwraca, to:

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$ 

Właściwie uruchomiłem tę samą linię na skrypcie, który utworzyłem vii poprawnie wyszukuje.


Nie rozumiem, dlaczego tr narzekałby, czy wpisałeś to samo, co zadałeś? grep nie znajdzie tego, czego chcesz, xdoc jest źle zdefiniowanym standardem. Nikt tak naprawdę nie wie, co jest w tych plikach, ludzie poddali go inżynierii wstecznej, najwyraźniej standard nie był pomocny.
ctrl-alt-delor

Odpowiedzi:


29

grepto narzędzie do przetwarzania tekstu. Oczekuje, że ich dane wejściowe będą plikami tekstowymi . Wygląda na to, że to samo dotyczy trsystemu macOS (chociaż trma obsługiwać pliki binarne).

Komputery przechowują dane jako sekwencje bajtów . Tekst to ciąg znaków. Istnieje kilka sposobów kodowania znaków jako bajtów, zwanych kodowaniem znaków . De facto standardowym kodowaniem znaków w większości świata, szczególnie w OSX, jest UTF-8 , który jest kodowaniem zestawu znaków Unicode . Istnieje tylko 256 możliwych bajtów, ale ponad milion możliwych znaków Unicode, więc większość znaków jest kodowana jako wiele bajtów. UTF-8 jest kodowaniem o zmiennej długości: w zależności od znaku kodowanie znaku może zająć od jednego do czterech bajtów. Niektóre sekwencje bajtów nie reprezentują żadnego znaku w UTF-8. Dlatego istnieją sekwencje bajtów, które nie są poprawnymi plikami tekstowymi UTF-8.

trnarzeka, ponieważ napotkał taką sekwencję bajtów. Oczekuje pliku tekstowego zakodowanego w UTF-8, ale widzi dane binarne, które nie są poprawne UTF-8.

Dokument Microsoft Word nie jest plikiem tekstowym: jest to dokument edytora tekstu. Formaty dokumentów przetwarzania tekstu kodują nie tylko tekst, ale także formatowanie, osadzone obrazy itp. Format Word, podobnie jak większość formatów przetwarzania tekstu, nie jest plikiem tekstowym.

Możesz poinstruować narzędzia do przetwarzania tekstu, aby działały na bajtach, zmieniając ustawienia regionalne . W szczególności wybierz lokalizację „C”, co w zasadzie oznacza „nic szczególnego”. W wierszu polecenia możesz wybrać ustawienia regionalne ze zmiennymi środowiskowymi .

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

Nie spowoduje to wyemitowania błędu, ale nie przyniesie też nic pożytecznego, ponieważ target-filenadal jest plikiem binarnym, który prawdopodobnie nie zawiera większości podanych ciągów wyszukiwania.

Nawiasem mówiąc, tr '\r' '\n'nie jest to bardzo przydatne polecenie, chyba że masz pliki tekstowe z systemu Mac OS 9 lub starszego. \r(powrót karetki) był separatorem nowej linii w Mac OS przed Mac OS X. Od OSX separatorem nowej linii jest \n(przesunięcie wiersza, standard unix), a pliki tekstowe nie zawierają znaków powrotu karetki. Windows używa dwuznakowej sekwencji CR-LF do reprezentowania podziałów linii; tr -d '\r'przekonwertowałby plik tekstowy Windows na plik tekstowy Unix / Linux / OSX.

Jak więc szukać w dokumencie Word z wiersza poleceń? Dokument .docxWord jest w rzeczywistości archiwum zip zawierającym kilka plików, z których główne są w formacie XML .

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

Mac OS X zawiera narzędzie zipgrep do przeszukiwania plików zip.

zipgrep DeCSS Position-Paper-Final-Version.docx

Wynik nie będzie bardzo czytelny, ponieważ pliki XML w formacie docx składają się głównie z jednej ogromnej linii. Jeśli chcesz przeszukać główny tekst dokumentu, wypakuj plik word/document.xmlz archiwum. Zauważ, że oprócz tekstu dokumentu, plik ten zawiera znaczniki XML, które reprezentują strukturę dokumentu. Możesz nieco masować znaczniki XML, sedaby podzielić je na łatwe do zarządzania linie.

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

1
+1 za dobre podsumowanie i dodatkowe bity. Mam jednak jedną rzecz do powiedzenia. Aby sformatować plik XML, możesz go użyć xml_ppw pakiecie xml-twig-toolsna Debian Gnu + Linux (nie znam Maca).
ctrl-alt-delor

2
Program Excel dla komputerów Mac 2011 zapisuje pliki CSV z zakończeniami wiersza \, więc to wywołanie tr jest w rzeczywistości bardzo przydatne i przydatne.
Noah Yetter

1
Podobnie jak Outlook 2011 dla komputerów Mac podczas eksportowania listy kontaktów rozdzielanej tabulatorami.
Ivan X

1
Cóż, nie mam wystarczającej reputacji, aby głosować za tym, ale ta odpowiedź jest całkowicie niepoprawna. Zaczyna się od „ tr[...] oczekują, że ich dane wejściowe będą plikami tekstowymi.”; podczas gdy specyfikacja POSIX wyraźnie stwierdza „Standardowym wejściem może być dowolny typ pliku”. . Popraw swoją odpowiedź.
7heo.tk

@ 7heo.tk „ta odpowiedź jest całkowicie błędne” jest exageration brutto, ale masz rację, trto powinien przetwarzać wejście binarne (w szczególności, to ma proces NULL bajty poprawnie). POSIX nie określa jednak jasno, w jaki sposób ma postępować z danymi wejściowymi, które nie są ciągiem znaków. (Gdybym był implementatorem, przekazywałbym niepoprawne sekwencje bajtów przez niezmodyfikowane (lub usunąłem je -s) i zgłaszałem wadę standardowej komisji.) Najwyraźniej tr macOS narzeka na nie.
Gilles „SO- przestań być zły”

13

Podejrzewam, że twój charmap z ustawień regionalnych to UTF-8, więc będziesz mieć problemy z plikami binarnymi. Po prostu przejdź do ustawień regionalnych C:

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

możesz użyć nawiasów, aby uniknąć dwukrotnego określenia języka. LC_ALL=C ( tr '\r' '\n' < target-file | grep search-string ). Jednak docx nie jest lokalny w języku C. Jest utf16 i jest skompresowany i złożony i nikt nie zgadnie. Chciałbym wyglądać jak narzędzie, które może przekonwertować go na inny format, który można przetwarzać np. HTML lub ODT (ODT jest również skompresowany, ale dobrze zdefiniowany i łatwy do interpretacji).
ctrl-alt-delor

1
Składnia z nawiasami (nawiasami) nie działa ze wszystkimi powłokami (nie bash, nie zsh, nie dash). Następnie, jeśli chodzi o plik MS Word, to zależy. Mam kilka takich plików, w których stringspolecenie podaje czysty tekst.
vinc17

Alternatywnie ( export LC_ALL=C; tr '\r' '\n' < target-file | grep search-string; )powinien działać.
vinc17

1
stringsma super moce: potrafi czytać pliki, które nie są tylko utf-8 lub tekstem ASCII.
ctrl-alt-delor

Przepraszam za ()rzecz, która moim zdaniem zadziała, dzięki @ vinc17 za naprawę.
ctrl-alt-delor
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.