ファイルがバイナリ ファイルかどうかを確認するにはどうすればよいですか?
たとえば、コンパイルされた c ファイル。
あるディレクトリからすべてのファイルを読み取りたいのですが、バイナリ ファイルを無視したいです。
ファイルがバイナリ ファイルかどうかを確認するにはどうすればよいですか?
たとえば、コンパイルされた c ファイル。
あるディレクトリからすべてのファイルを読み取りたいのですが、バイナリ ファイルを無視したいです。
使用ユーティリティfile
、使用例:
$ file /bin/bash
/bin/bash: Mach-O universal binary with 2 architectures
/bin/bash (for architecture x86_64): Mach-O 64-bit executable x86_64
/bin/bash (for architecture i386): Mach-O executable i386
$ file /etc/passwd
/etc/passwd: ASCII English text
$ file code.c
code.c: ASCII c program text
バイナリファイルの除外から適応
find . -exec file {} \; | grep text | cut -d: -f1
私が使う
! grep -qI . $path
私が見ることができる唯一の欠点は、空のファイルバイナリを考慮することですが、それが間違っているかどうかを判断するのは誰ですか?
perl -E 'exit((-B $ARGV[0])?0:1);' file-to-test
「テストするファイル」がバイナリであるときはいつでもチェックするために使用できます。上記のコマンドは、バイナリ ファイルではコード 0 で終了します。それ以外の場合、終了コードは 1 になります。
テキスト ファイルのリバース チェックは、次のコマンドのようになります。
perl -E 'exit((-T $ARGV[0])?0:1);' file-to-test
同様に、「テストするファイル」がテキスト (バイナリではない) の場合、上記のコマンドはステータス 0 で終了します。
-B
および-T
コマンドを使用したチェックの詳細を参照してくださいperldoc -f -X
。
-T
ファイル テスト オペレータを使用してプレーン ファイルであることを確認した後、Perl の組み込みファイル テスト オペレータを使用し-f
ます。
$ perl -le 'for (@ARGV) { print if -f && -T }' \
getwinsz.c a.out /etc/termcap /bin /bin/cat \
/dev/tty /usr/share/zoneinfo/UTC /etc/motd
getwinsz.c
/etc/termcap
/etc/motd
そのセットの補足は次のとおりです。
$ perl -le 'for (@ARGV) { print unless -f && -T }' \
getwinsz.c a.out /etc/termcap /bin /bin/cat \
/dev/tty /usr/share/zoneinfo/UTC /etc/motd
a.out
/bin
/bin/cat
/dev/tty
/usr/share/zoneinfo/UTC
でバイナリファイルを除外するのは一種の強引ですtr -d "[[:print:]\n\t]" < file | wc -c
が、ヒューリスティックな推測でもありません。
find . -type f -maxdepth 1 -exec /bin/sh -c '
for file in "$@"; do
if [ $(LC_ALL=C LANG=C tr -d "[[:print:]\n\t]" < "$file" | wc -c) -gt 0 ]; then
echo "${file} is no ASCII text file (UNIX)"
else
echo "${file} is ASCII text file (UNIX)"
fi
done
' _ '{}' +
ただし、次のブルート フォース アプローチを使用するgrep -a -m 1 $'[^[:print:]\t]' file
と、かなり高速に見えます。
find . -type f -maxdepth 1 -exec /bin/sh -c '
tab="$(printf "\t")"
for file in "$@"; do
if LC_ALL=C LANG=C grep -a -m 1 "[^[:print:]${tab}]" "$file" 1>/dev/null 2>&1; then
echo "${file} is no ASCII text file (UNIX)"
else
echo "${file} is ASCII text file (UNIX)"
fi
done
' _ '{}' +
grep
バイナリが印刷不可能な文字 (スペース、タブ、改行文字などの空白文字を除く) を含むファイルを意味すると仮定すると、これは機能する可能性があります (BSD と GNU の両方):
$ grep '[^[:print:][:blank:]]' file && echo Binary || echo Text
注: GNUは NULL 文字のみを含むファイルをテキストとして報告しますが、 grep
BSD バージョンでは正しく動作します。
その他の例については、次を参照してください: How do I grep for all non-ASCII characters .