無粋な日々に

頭の中のメモ。分からないことを整理する

ファイルをバイト単位で比較:cmpコマンド

2つのzipファイルを比較したい場合など、バイナリレベルでファイルを比較したいことがあります。こういう場合はシェルのcmpコマンドで比較すると良いです。

FILE1FILE2を比較する場合の構文は以下になります。

cmp FILE1 FILE2

完全に一致していれば何も出力されず、不一致の場合は

file1.tar.gz file2.tar.gz differ: char 5, line 1

のように比較した各ファイルパスとどの部分が異なるのかを標準出力に出力してくれます。(ここではfile1.tar.gzfile2.tar.gzを比較しています)

また差異の有無によって終了ステータスコードが異なり、差があった場合はexit status = 1、差がなかった場合は exit status = 0となります。差の有無によって分岐処理などしたい場合はexit statusで判断すれば良いかなと思います。

例:2つのディレクトリにある全ファイルをバイト単位で比較する

使用例として、2つのディレクトリにある同名のファイル同士を比較し、差があるときだけメッセージを出すbashスクリプトを書いてみます。差の有無の判断はexit statusで行っています。

#! /bin/bash
# 2つのディレクトリにある同じ名前のファイル同士を比較し、差があるときだけメッセージを出す

dir1=src1/  # 1つ目のディレクトリ
dir2=src2/  # 2つ目のディレクトリ

fpaths=${dir1}*  # 第1ディレクトリの全ファイルパスを取得

# ファイルパスをループ
i=0
for f1path in $fpaths; do
  fnm=`basename $f1path`
  # echo $fnm
  f2path=${dir2}${fnm}
  cmt=`cmp $f1path $f2path`  # 2つのファイルを比較
  if [ $? -eq 1 ]; then
    echo $cmt  # 差があった場合は、メッセージを表示
    i=$(( $i + 1 ))  # 差があったファイル数をカウントしておく
  fi
done

# 差が1つもなかった場合はその旨を表示
if [ $i -eq 0 ]; then
  echo 'All file pairs are the same.'
fi

検証環境:

macOS Catalina

GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin19) Copyright (C) 2007 Free Software Foundation, Inc.

コードはこちらです。


shellとかRとか、少し触らないとすぐに忘れてしまいます。栓が抜けた湯船のように、蛇口から入ってくる水より多くの水が抜けていきます。そのうちスッカラカンになりそうな。。。日々精進