trは「不正なバイトシーケンス」について不平を言っています


24

私はUNIXが初めてで、Kirk McElhearnの「The Mac OS X Command Line」を使用していくつかのコマンドを習得しています。

私が使用しようとしていますtrgrepなるように、私は、通常の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 14

回答:


29

grepテキスト処理ツールです。入力はテキストファイルであると想定しています。同じことがtrmacOSにも当てはまるようtrです(バイナリファイルをサポートするはずですが)。

コンピュータは、データをバイトシーケンスとして格納します。テキストは一連の文字です。文字をバイトとしてエンコードするには、文字エンコードと呼ばれるいくつかの方法があります。世界のほとんど、特にOSXでの事実上の標準文字エンコードはUTF-8で、これはUnicode文字セットのエンコードです。256バイトしかありませんが、100万を超えるUnicode文字が可能なため、ほとんどの文字は複数バイトとしてエンコードされます。UTF-8は可変長エンコードです。文字に応じて、1文字から4バイトで文字をエンコードできます。バイトシーケンスの中には、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(キャリッジリターン)は、Mac OS X以前のMac OSの改行セパレーターでした。OSXから、改行セパレーターは\n(改行、Unix標準)であり、テキストファイルにはキャリッジリターンが含まれていません。Windowsは2文字のシーケンスCR-LFを使用して改行を表します。tr -d '\r'WindowsテキストファイルをUnix / Linux / OSXテキストファイルに変換します。

それでは、コマンドラインからどのようにWord文書を検索できますか?.docxWord文書が実際にzipアーカイブ複数のファイル、にある主なもの含むXMLを

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

Mac OS Xには、zipファイル内を検索するzipgrepユーティリティが含まれています。

zipgrep DeCSS Position-Paper-Final-Version.docx

docx形式のXMLファイルの大部分は1つの大きな行で構成されているため、結果はあまり読みやすくなりません。ドキュメントの本文テキスト内を検索する場合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-toolsDebian Gnu + Linux(macを知らない)のパッケージにあるxmlを使用できます。
ctrl-alt-delor 14

2
Excel for Mac 2011では、\ r行末でCSVファイルが保存されるため、このtr呼び出しは実際、非常に関連性が高く便利です。
ノアYetter

1
Outlook for Mac 2011と同様に、タブ区切りの連絡先リストをエクスポートするとき。
イヴァンX

1
まあ、これを支持するほどの評判はありませんが、この答えはまったく間違っています。「tr[...]入力がテキストファイルであることを期待してください」で始まります。一方、POSIX仕様が明確に述べ、「標準入力は、ファイルの任意のタイプにすることができます。」。答えを修正してください。
7heo.tk

7heo.tk @「この答えは全く間違っています」総exagerationですが、あなたしている右、trされるはず(特に、それはプロセスnullになっています正しくバイト)のバイナリ入力を処理します。ただし、POSIXは、文字のシーケンスではない入力をどのように処理するかを明確に指定していません。(私が実装した場合、私はそのままを通じて不正なバイト列を渡す(またはそれらを削除したい-s)、および標準委員会で欠陥を上げる。)明らかに、MacOSののTRはそれらについて文句を言います。
ジル 'SO-悪であるのをやめる'

13

ロケールからのcharmapはUTF-8なので、バイナリファイルに問題があると思います。Cロケールに切り替えるだけです。

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

ブラケットを使用して、言語を2回指定することを回避できます。LC_ALL=C ( tr '\r' '\n' < target-file | grep search-string )。ただし、docxはCローカルではありません。utf16であり、zip形式で複雑であり、誰でも推測できます。htmlやodtなどの処理可能な別の形式に変換できるツールを使用しているように見えます(odtも圧縮されていますが、明確に定義されており、簡単に解釈できます)。
ctrl-alt-delor 14

1
括弧(括弧)を使用した構文は、すべてのシェル(bash、zsh、dashではない)で機能しません。次に、MS Wordファイルについては、依存します。stringsコマンドがクリアテキストを提供するようなファイルがいくつかあります。
vinc17 14

または、動作する( export LC_ALL=C; tr '\r' '\n' < target-file | grep search-string; )はずです。
vinc17 14

1
strings超強力:utf-8やASCIIテキストだけではないファイルを読むことができます。
ctrl-alt-delor 14

申し訳ありませんについて()、私はそれが仕事だろうと思った事、修正のために、@ vinc17に感謝。
ctrl-alt-delor 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.