概要
リレーショナルデータベースでいう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では区別されることがバグの原因となっていました。このコマンドによってサクッと差分を出力することができ、重宝しました。