uniq コマンドと集合演算

uniq command and set operations.

unix コマンドを多用する職種についていると、よく、

”2つのテキストファイルで重複している文字列をリストして!!”

とか、

”テキストファイルAからテキストファイルBに記載している文字列を除いてリストして!!"

とかする必要が出てきます(唐突)。

今回はそのようなときに大活躍する uniq コマンドの基本的なテクニックを紹介します。

準備

今回は紹介する uniq コマンドの他に sort コマンドを使います。

sort コマンドは、引数に渡したテキストファイルの内容を辞書順に並べて出力します。

uniq コマンドは仕様上、重複している文字列が連続している必要があります。あらゆる場面において、 uniq コマンドは sort コマンドと組み合わせで使います。

$ cat sort-sample-1.txt
ccc
bb
a
$ sort sort-sample-1.txt
a
bb
ccc

複数のテキストファイルを引数に渡した場合は、テキストファイルの内容を連結した上で辞書順に並べて出力します。

$ cat sort-sample-2.txt
ffffff
eeeee
dddd
$ sort sort-sample-1.txt sort-sample-2.txt
a
bb
ccc
dddd
eeeee
ffffff

サンプルの説明

今回は2つのテキストファイル(lang.txtjewel.txt)を用意します。それぞれのテキストファイルは一行につき1つの文字列を記載します。

テキストファイルは各行の文字列を要素とする集合と見なすことができます。

$ cat lang.txt
perl
php
ruby
$ cat jewel.txt
diamond
pearl
ruby

ベン図にすると以下のようになります。

基本のベン図

和集合

それでは、集合演算ぽいことをしていきましょう。まず最初は和集合です。各ファイルの文字列を重複無くリストします

和集合
$ sort lang.txt jewel.txt | uniq
diamond
pearl
perl
php
ruby

uniq コマンドの一番シンプルな使い方なので、オプションは不要です。

積集合

次は積集合です。重複している文字列のみリストします

積集合
$ sort lang.txt jewel.txt | uniq -d
ruby

-d オプションを使います。

重複削除(対象差)

次は重複している文字列のみを除外してリストします。対象差といいます。あまり業務上は利用しませんが、この次の例(差集合)を理解するのに必要です。

対象差
$ sort lang.txt jewel.txt | uniq -u
diamond
pearl
perl
php

-u オプションを使います。

差集合

次は差集合です。片方のテキストファイルにある文字列から、もう片方のテキストファイルにある文字列を除外してリストします。ブラックリストを使った運用時に利用できるテクニックです。

差集合
$ sort lang.txt jewel.txt jewel.txt | uniq -u
perl
php

-u オプションを使います。対象差と同じですが、 sort コマンドの引数に jewel.txt を2回渡しています。これにより、 jewel.txt にリストされた文字列は、必ず2回以上現れます。したがって、 jewel.txt にリストされた単語は必ず除外されます。


いかがでしょうか? 今回使用したオプションでほとんどの場合対応できるとおもいます。

unix コマンドには知っておくと便利なオプションが数多くあります。今後も折を見て紹介いたします。