grepはファイルがバイナリファイルであるかどうかを確認しますか?

grepはファイルがバイナリファイルであるかどうかを確認しますか?

頻繁に作業する大容量のutf-8テキストファイルがあり、grep最近このgrepファイルはバイナリファイルとして報告され始めました。を使用して検索を続けることはできますが、ファイルがバイナリであると判断したgrep -a変更が何であるかを知りたいです。

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

file私のファイルを次のように識別します。

UTF-8 Unicode英語テキスト、長い行

文字/行などをどのように見つけることができますか?私のファイルの中で何がこの変更を引き起こしましたか?


類似して重複しない質問19907NULの可能性に対処しますが、grep -Pc '[\x00-\x1F]'NULや他のANSI制御文字がないと言います。

答え1

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

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

テキストエディタvimを使用して、テキストファイルに制御文字を挿入して直接テストできます。挿入モードに入り、Ctrl-Vを押してから制御文字を押します。

答え2

一般的な最新のgrep実装では、ファイルが内部的にnullバイトの場合にのみファイルを「バイナリ」として宣言する必要があります。他の人は大丈夫でしょう。

私はあなたが使用しているgrepの実装について話すことはできません...

答え3

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#説明

これが唯一の他の可能性ですNUL

GNUgrepソースコードの解釈は、次の結論につながります。grepがファイルをバイナリとして扱うのはなぜですか?

関連情報