(Linux)cmpコマンド

6-1.比較・差分

ドラマ『家売るオンナ』(2016)

北川景子が不動産営業の無表情なチーフしてます。
仕事は完璧です。家を売るために手は抜きません。買い手の家族構成や将来の夢や今一番しなきゃならないことを考慮して、物件を選んでくれます。
しかも強引です。捕まったら買うまで許してくれない雰囲気です。不動産は、家を買う方が主導権があるのかと思ったら、完全に売り手が握ってますね。

細部まで比較して、より条件の良い物件を探すのって、結構しんどかったりします。一番良いものを確実に探してきてくれる、こんな営業がいたら全部お任せしたいって人もいると思います。

今回は比較コマンドのcmpを使ってみます。まずは3Byte程度のバイナリを生成して比較してみます。

~$ echo -ne "\x10\x20\x30" > a
~$ echo -ne "\x15\x25\x35" > b
~$ cmp a b
a b 異なります: バイト 1、行 1
~$ cmp -l a b
1  20  25
2  40  45
3  60  65
~$ 

一番左が差分のあるByteのインデックスです。続いて、引数で指定したファイル順に値が8進数で表示されます。

ファイルbをベースに2Byte目の値をファイルaと一致させたファイルcを作ってaとcを比べてみましょう。

~$ sed "s/\x25/\x20/" b > c
~$ cmp a c
a c 異なります: バイト 1、行 1
~$ cmp -l a c
1  20  25
3  60  65
~$ 

別の値でも試してみます。

~$ echo -ne "\x10\x20\x30" > a
~$ echo -ne "\x20\x30\x40" > b
~$ cmp -l a b
1  20  40
2  40  60
3  60 100
~$ 

ファイルaの1Byte目をスキップします。3つ目の引数にスキップ数が指定できます。

~$ cmp -l a b 1
cmp: a でファイル終端 (EOF) に達しました
~$ 

両ファイルは同サイズなので、ファイルaを1Byteスキップしたら、先に終端に達します。

コピーしたファイルは一致しますが、cmp時に片側をスキップさせると不一致します。

~$ seq 10 | perl -ne 'print chr' > a
~$ cp a b
~$ cmp -l a b 1
1   2   1
2   3   2
3   4   3
4   5   4
5   6   5
6   7   6
7  10   7
8  11  10
9  12  11
cmp: a でファイル終端 (EOF) に達しました
~$ 

終端まで比較せずに、指定した数だけ比較したい場合は、-nオプションを使います。9Byte分比較してみましょう。

~$ cmp -ln9 a b 1
1   2   1
2   3   2
3   4   3
4   5   4
5   6   5
6   7   6
7  10   7
8  11  10
9  12  11
~$ 

比較して一致していたらコマンドステータスは0で返ります。不一致は1になります。

~$ cmp a b;echo $?
0
~p$ cmp a b 1;echo $?
a b 異なります: バイト 1、行 1
1
~$ 

cmpで表示される値は8進数ですが、16進数で確認したい場合がほとんどかと思います。その時は2列目と3列目を16進数に置換すれば良いです。

~$ cmp -ln9 a b 1 | perl -pe 's/ +(\d+)/sprintf("\t%X",oct $1)/ge'
1	2	1
2	3	2
3	4	3
4	5	4
5	6	5
6	7	6
7	8	7
8	9	8
9	A	9
~$ 

コメント

タイトルとURLをコピーしました