概要
リレーショナルデータベースでいうEXCEPT
をシェルコマンドで実現します。
内容
SELECT id FROM a
EXCEPT
SELECT id FROM b;
それぞれa.txt
、b.txt
に集合の中身が書かれているとします。ここで、a-b
(a.txt
にはあるが、b.txt
にはないもの)を出力するには、下記コマンドを実行します。
cat b.txt b.txt a.txt | sort | uniq -u
具体例と解説
a.txt
aaa
bbb
cccc
dddd
b.txt
cccc
dddd
ee
ff
出力
aaa
bbb
解説
-
uniq -u
コマンドは、ユニークな行(重複していない行)を出力します -
uniq
コマンドに掛ける前にsort
コマンドでソートする必要があります -
cat b.txt b.txt a.txt
をすることで-
a.txt
にもb.txt
にも含まれる行は、3行になるため、uniq -u
で除外される -
b.txt
のみに含まれる行は、2行になるため、uniq -u
で除外される -
a.txt
のみに含まれる行は、1行のみになるため、uniq -u
で出力される
-
より実践的な具体例
ファイルバックアップ
~/work
ディレクトリと~/backup
ディレクトリの差分を確認し、~/backup/
されていないファイルを出力します。削除されたファイルは~/backup/
にあっても良しとします。(この場合だったらrsync -av --dry-run ~/work/ ~/backup/
でも良いのかも。)
cd ~/work
ls
# > aaa bbb cccc dddd
find . -type f > ../work_filelist.txt
cd ~/backup
touch cccc dddd ee ff
find . -type f > ../backup_filelist.txt
cat backup_filelist.txt backup_filelist.txt work_filelist.txt | sort | uniq -u >need_copy.txt
ファイルにて連携しているシステムのエラー調査
私がこれらのコマンドを活用したのは、ファイル連携しているシステムのエラー調査でした。
実は、このサーバはWindowsサーバ(NTFS)とLinuxサーバ(ext4)間の連携で、Windowsでは大文字小文字は無視され、Linuxでは区別されることがバグの原因となっていました。このコマンドによってサクッと差分を出力することができ、重宝しました。