カイワレの大冒険 Third

技術的なことや他愛もないことをたまに書いてます

ファイル内容の差異を分かりやすく示してくれる「comm」コマンドの紹介

ファイル間の差異を表で示して、集合っぽく扱えるコマンドがあるのでご紹介。

どういうことができるの?

ファイルAとファイルBという二つのファイル間の差異を調べるのであれば、diffコマンドを使えばいいわけですが、
AとBのなかで「Aにだけ含まれているもの」「Bにだけ含まれているもの」「AにもBにも含まれているもの」というようなことを調べたいというときがあったりします。

そんなときに便利な「comm」コマンドのご紹介。

実際やってみる

まず簡単に使ってみましょう。test1とtest2というファイルを使って簡単に。

$ cat test1
test1
test2

$ cat test2
test1
test3

$ comm test test2
		test1
test2
	test3

オプションをつけないと3列に出力されますが、「左列」が最初の引数のファイル(test1)のみに書かれたもの、中央列が第2引数のファイル(test2)のみに書かれたもの、右列が両方のファイルに書かれたものとなります。

どういうとき使えるの?

たとえば、group1.txtとgroup2.txtにはそれぞれIPアドレスやその設定などが書かれていたとします。muninの設定ファイルでもtomahawkを走らせるためのサーバ一覧でもhostsファイルでもなんでもよいでしょう。

このgroup1.txtとgroup2.txtにおいて、上述したようなどちらに含まれているか否かをみたいわけですね。たとえば、group1.txtにだけ含まれているIPアドレスの一覧を抜き取りたかったりします。

ということでやってみましょう。まずIPアドレスだけを正規表現で取ってきます。

$ grep -o -e "[0-9|0-9]\+\.[0-9|0-9]\+\.[0-9|0-9]\+\.[0-9|0-9]\+" group1.txt > servers_group1.list
$ grep -o -e "[0-9|0-9]\+\.[0-9|0-9]\+\.[0-9|0-9]\+\.[0-9|0-9]\+" group2.txt > servers_group2.list

あとは、commコマンドでオプションを渡すだけです。今回はgroup1.txtに含まれるIPアドレスだけを知りたいので、「-23」をオプションで指定します。

$ comm -23 servers_group1.list servers_group2.list > only_group1.list

簡単ですね。

終わりに

まぁ、含まれるか否かであれば、一行ずつ読み込んで含まれているかどうかを比較したり、他にも方法はあるかもしれません。ただ、まぁ簡単に使えるコマンドなので、意外なときに役に立ったりするコマンドだったりします。ということで、commコマンドの紹介でした。


P.S.
切ないことにcommコマンドはソートされていないと綺麗に比較してくれないようです。なので、「sort -u」などを一回かませて、その上でcommコマンド使ったほうがよいでしょうね。まぁ、その辺は仕方がないかもですな。