【Linux】Linuxコマンドで集合演算するには ~ sort / uniq ~

■ はじめに

 例えば、
ListAファイルに、「全テーブル一覧」が格納されていて
ListBファイルに、「現在のDBに入っているテーブル一覧」が格納されていた場合
ListAファイルに対して、ListBファイルにはないものを出力したい。
そういったことを行う必要がでてきたので、メモっておく

なお、以下のサイトが、やりたいことどんぴしゃで助かった。
感謝。。。

https://medium.com/veltra-engineering/uniq-command-and-set-operations-bd4f04b17d9a

補足

 これは、あくまで例であり
SQLであれば、CREATE IF EXISTS文で済んでしまえばいい

目次

【1】集合演算する際に必要なコマンド一覧
 1)sortコマンド
 2)uniqコマンド
【2】Tips:ファイル加工で役立ちそうなコマンド
 1)空白行削除
 2)大文字/小文字統一
【3】サンプル
 1)和集合 (全部)
 2)積集合 (重複のみ)
 3)対象差 (重複削除)
 4)差集合 (一方しかないもの抽出)

【1】集合演算する際に必要なコマンド一覧

1)sortコマンド

* テキストファイルを“行単位で並べ替える”

https://atmarkit.itmedia.co.jp/ait/articles/1611/09/news020.html

構文

# ファイルを複数指定可能なのがポイント!
sort [オプション] [ファイル1 ファイル2]

主なオプション

Options Explanations
-r / --reverse 逆順で並べ替える
-f / --ignore-case 大文字/小文字を区別しないで並べ替える
-b / --ignore-leading-blanks 先頭の空白を無視して並べ替える

コマンド例

$ echo -e "ccc\nddd\naaa\n" > list-a.txt

$ cat list-a.txt
ccc
ddd
aaa

# 「grep -v '^$'」は空行削除
$ sort list-a.txt | grep -v '^$' > sorted-list-a.txt

$ cat sorted-list-a.txt
aaa
ccc
ddd

2)uniqコマンド

* 重複している行を削除する

https://atmarkit.itmedia.co.jp/ait/articles/1611/14/news021.html

構文

# オプション含めて利用することで実現可能
uniq [オプション] 入力ファイル [出力ファイル]

主なオプション

Options Explanations
-d / --repeated 重複した行だけを出力する
-u / --unique 重複していない行だけを出力する

【2】Tips:ファイル加工で役立ちそうなコマンド

* sortコマンドのOptionsでも可能だが、せっかく調べたのでメモっておく

1)空白行削除

# 空白行削除
$ grep -v '^$' list-a.txt
ccc
ddd
aaa

2)大文字/小文字統一

# 大文字に統一
$ echo  'Hello World!!' | awk '{print toupper($0)}'
HELLO WORLD!!

# 小文字に統一
$ echo  'Hello World!!' | awk '{print tolower($0)}'
hello world!!

【3】サンプル

集合図

* 共通は「ccc」

+--list-a---*-----+--list-b--*
| aaa       |     | bbb      |
|           | ccc |          |
| ddd       |     | eee      |
+-----------*-----+----------*

テストデータ作成

$ echo -e "ccc\nddd\naaa\n" > list-a.txt
$ echo -e "ccc\neee\nbbb\n" > list-b.txt

1)和集合 (全部)

コマンド例

# sort <ファイル1> <ファイル2> | uniq 
$ sort list-a.txt list-b.txt | uniq | grep -v '^$'
aaa
bbb
ccc
ddd
eee

2)積集合 (重複のみ)

コマンド例

# sort <ファイル1> <ファイル2> | uniq  -d
$ sort list-a.txt list-b.txt | uniq  -d | grep -v '^$'
ccc

メモ

* 「1)和集合」に、uniq  コマンドの -dオプション(重複した行だけを出力)
 を付加しただけ

3)対象差 (重複削除)

コマンド例

# sort <ファイル1> <ファイル2> | uniq  -u
$ sort list-a.txt list-b.txt | uniq  -u | grep -v '^$'
aaa
bbb
ddd
eee

メモ

* 「1)和集合」にuniq  コマンドの -uオプション(重複していない行だけを出力)
 を付加しただけ

4)差集合 (一方しかないもの抽出)

コマンド例

# sort <ファイル1> <ファイル2> <ファイル2> | uniq  -d
$ sort list-a.txt list-b.txt list-b.txt | uniq  -u | grep -v '^$'
aaa
ddd

# sort <ファイル1> <ファイル2> <ファイル1> | uniq  -d
$ sort list-a.txt list-b.txt list-a.txt | uniq  -u | grep -v '^$'
bbb
eee

メモ

*  「3)対象差 (重複削除)」に、sortコマンドで
 list-b.txt にリストされた文字列は、必ず2回以上現れることにより、
 list-b.txt にリストされた単語は必ず除外される

差集合 の 例

list-a.txt list-b.txt list-b.txt 出力
aaa - - aaa
- bbb bbb - (除外)
ccc ccc ccc - (除外)
ddd - - ddd
- eee eee - (除外)

参考文献

https://medium.com/veltra-engineering/uniq-command-and-set-operations-bd4f04b17d9a

関連記事

シェル について ~入門編~
https://dk521123.hatenablog.com/entry/2014/10/23/005406
awk コマンド
https://dk521123.hatenablog.com/entry/2019/11/22/223043
sedコマンド
https://dk521123.hatenablog.com/entry/2019/11/23/101625
grep / egrep / fgrepコマンド
https://dk521123.hatenablog.com/entry/2017/08/06/213100