LoginSignup
13
15

More than 5 years have passed since last update.

ファイルがバイナリ形式かどうか判別する

Posted at

シェルスクリプトの file コマンドを利用する

file コマンドを利用するといい感じでファイルタイプを判定してくれる。

オプションなしで実行
$ file a.sh b.png c.xml d.java e.jar 
a.sh:   Bourne-Again shell script text executable
b.png:  PNG image data, 800 x 534, 8-bit/color RGB, non-interlaced
c.xml:  XML  document text
d.java: ASCII c program text
e.jar:  Zip archive data, at least v1.0 to extract

--mime オプションで mime-type 形式で出力してくれる。

--mimeオプションで実行
$ file --mime a.sh b.png c.xml d.java e.jar 
a.sh:   text/x-shellscript; charset=us-ascii
b.png:  image/png; charset=binary
c.xml:  application/xml; charset=us-ascii
d.java: text/x-c; charset=us-ascii
e.jar:  application/zip; charset=binary

この出力に charset=binary が含まれているかどうかをチェックするという方法。

check.sh
isBinary() {
  a=$(file --mime "$1" | grep "charset=binary")
  if [ -n "$a" ]; then return 0; fi
  return 1
}
for f in a.sh b.png c.xml d.java e.jar; do
  isBinary $f && echo $f is binary || echo $f is not binary
done
check.sh実行結果
$ sh check.sh 
a.sh is not binary
b.png is binary
c.xml is not binary
d.java is not binary
e.jar is binary

参考リンク

Git 内部のバイナリ判定ロジックを利用する

Git では diff や merge でバイナリファイルかどうかを判定しており、その判定ロジックを利用しようという方法。
ただし内部の判定処理は明示的に公開されているものではないので、特定コマンドの出力結果パターンをチェックする。

check.sh
isBinary() {
    p=$(printf '%s\t-\t' -)
    t=$(git diff --no-index --numstat /dev/null "$1")
    case "$t" in "$p"*) return 0 ;; esac
    return 1
}
for f in a.sh b.png c.xml d.java e.jar; do
  isBinary $f && echo $f is binary || echo $f is not binary
done

これで file コマンドを利用した場合と同様な結果が得られる。

check.sh実行結果
$ sh check.sh
a.sh is not binary
b.png is binary
c.xml is not binary
d.java is not binary
e.jar is binary

git diff --numstat で追加/削除の行数が出力されるが、バイナリの場合は行数とかカウントできないよね、ってことで以下のように出力結果パターンが変わることをチェックしているという。

$ git diff --no-index --numstat /dev/null a.sh 
314     0       /dev/null => a.sh

$ git diff --no-index --numstat /dev/null b.png 
-       -       /dev/null => b.png

参考リンク

13
15
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
15