grepはファイルがバイナリであるとどのように判断しますか?


8

よく検索する大きなutf-8テキストファイルを持っていgrepます。最近grep、それがバイナリファイルであると報告し始めました。で引き続き検索できgrep -aますが、どのような変更によってファイルがバイナリであると判断されたのでしょうか。

先月のコピーがあり、ファイルはバイナリとして検出されなくなりdiffましたが、20,000行を超えるため、実用的ではありません。

file 私のファイルを

行が非常に長いUTF-8 Unicode英語テキスト

文字/行/その他を見つけるにはどうすればよいですか。この変更を引き起こしている私のファイルで?


同様の、重複していない質問19907はNULの可能性をカバーgrep -Pc '[\x00-\x1F]'していますが、NULや他のANSI制御装置がないと述べています。


これをこの順序で試してみます。1. strace / ltraceを使用して実行し、「バイナリ」メッセージの原因となっている入力を確認します。2. grepのソースを確認して読み取ります
ott--

@muru:私はgnu grepを使用していますが、他のバージョンの答えがわかれば、私も興味があります。
Charles

奇数。nulといくつかEscのが含まれていることがわかっているファイルがあります。私はそれらのためにgreppingを試みました。escs(\x1B)は見つかりましたが、nulは表示されませんでした。上記のテストは、Escs を含む行に対して1を示しましたが、を含まない範囲に対しては何も示しませんでした\x1B。私はそのテストを信用しません。grep -zc .代わりに試してください(nulファイル内のの数より1つ多いはずです)。(また、を使用し[[:cntrl:]]た方がよい場合もあります。)
muru

また、次のsed -z 's/.*\(....\)$/\1/' foo | od -cことも試してください:(あるNUL場合)の前にいくつかの文字を表示すると、問題が発生する可能性があります。
muru

@muru:私にsed-zオプションがありません:sed: invalid option -- 'z'
Charles

回答:


2

ファイルにnull文字が存在しているようです。(通常は^ @と表示されます)テキストファイルにさまざまな制御文字(たとえば、削除、^?など)を入力し、null文字のみがgrepに考慮させましたバイナリ。これはgrepに対してのみテストされました。たとえば、lessコマンドとdiffコマンドでは、メソッドが異なる場合があります。制御文字は一般に、バイナリ以外では表示されません。例外は、空白文字(改行(^ M)、タブ(^ I)、フォームフィード(^ L)、垂直タブ(^ K)、およびリターン(^ J)です。

ただし、アラビア語や中国語の文字などの外国語の文字は標準のASCIIではなく、制御文字と混同される可能性があります。たぶんそれがnull文字だけなのです。

テキストエディタvimを使用して、制御文字をテキストファイルに挿入することで、自分でテストできます。挿入モードに移動し、control-vを押してから、制御文字を押します。


2

典型的な最新のgrep実装では、内部にnullバイトがある場合にのみ、ファイルを「バイナリ」として宣言する必要があります。それ以外は大丈夫です。

使用しているgrep実装について話すことはできません...


1

mbrlen()によるエンコーディングエラーにより、GNU grep 2.24はそれをバイナリと見なします。

例えば:

export LC_CTYPE='en_US.UTF-8'
printf 'a\x80' | grep 'a'

\x80UTF-8 Unicodeポイントの最初のバイトにすることはできないため:https : //en.wikipedia.org/wiki/UTF-8#Description

これは他に唯一の可能性NULです。

grepこの結論につながるGNU ソースコードの解釈:grepがファイルをバイナリと見なすのはなぜですか?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.