ファイルを「バイナリ」または「テキスト」に分類する便利な方法はありますか?

ファイルを「バイナリ」または「テキスト」に分類する便利な方法はありますか?

grepなどの標準のUnixユーティリティは、diffいくつかの経験的な方法を使用してファイルを「テキスト」または「バイナリ」に分類します。 (たとえば、grep出力には次の行を含めることができますBinary file frobozz matches。)

zsh同様の「テキスト/バイナリ」分類を実行するためにスクリプトに適用できる便利なテストはありますか? (そういうものを除いてgrep '' somefile | grep -q Binary。)

(私はそのようなテストが必然的に経験的であるため不完全であることを知っています。)

答え1

file要求だけ無言のタイプtext/x-shellscriptなど様々な内容が出てきますがapplication/x-executable、「text」部分だけを確認するとかなり良い結果が得られそうです。たとえば(-b出力にファイル名がありません):

file -b --mime-type filename | sed 's|/.*||'

答え2

もう一つのisutf8方法その他のユーティリティ集める

ファイルが有効なUTF-8またはASCIIまたは短絡されている場合は0で終了し-q、エラーメッセージを印刷し(無音で)、そうでなければ1で終了します。

答え3

GNUが使用する経験的な方法を好む場合は、grep次のものを使用できます。

isbinary() {
  LC_MESSAGES=C grep -Hm1 '^' < "${1-$REPLY}" | grep -q '^Binary'
}

それファイルから読み込まれた最初のバッファから NUL バイトを検索します。(通常のファイルの場合は数キロバイトですが、パイプや/dev/randomソケット、または一部のデバイス(たとえば)の場合ははるかに少ない場合があります)。 UTF-8 ロケールでは、有効な UTF-8 文字を形成しないバイト列も表示します。LC_ALL英語以外の言語に設定されていない内容を想定してください。

このフォームを使用すると、グローバル修飾子${1-$REPLY}として使用できます。zsh

ls -ld -- *(.+isbinary)

一覧表示されますバイナリ文書。

答え4

file--mime-encodingファイルエンコーディングを検出するオプションがあります。

 $file --mime-encoding Documents/poster2.pdf 
Documents/poster2.pdf: binary
 $file --mime-encoding projects/linux/history-torvalds/Makefile 
projects/linux/history-torvalds/Makefile: us-ascii
 $file --mime-encoding graphe.tex 
Dgraphe.tex: us-ascii
 $file --mime-encoding software.tex 
software.tex: utf-8

file --mime-encoding | grep binaryこれを使用して、ファイルがバイナリかどうかを検出できます。長いテキストファイルで無効な文字で混乱する可能性がありますが、安定して動作します。

たとえば、cat誤ってバイナリファイルを開いて端末が破損するのを防ぐために、次のシェルスクリプトにエイリアスを追加しました。

#! /bin/sh -

[ ! -t 1 ] && exec /bin/cat "$@"
for i
do
    if file --mime-encoding -- "$i" | grep -q binary
    then
        hexdump -C -- "$i"
    else
        /bin/cat -- "$i"
    fi
done

関連情報