commコマンドを使って文字列でsort済みの2つのファイルの比較をし「片方だけに存在する行」「共通の行」を出力する

追記

「文字列でsort済みの」って入れ忘れてた。
manに

The comm utility reads file1 and file2, which should be sorted lexically,

って書いてある通り、「sorted lexically」でないとダメ(「sort -n」ではなく「sort」でsortする)

なので、

comm <(sort id_num.txt) <(sort id_even.txt)

ってやるのが確実

追記終わり



commコマンドの名前をすぐに忘れてしまい、ググっても「catしてuniq」とかそういうのしか出てこなくて「あのコマンド名なんだっけなー」ってなるのでメモ残す

やりたいこと

  • 2つのファイルがあり、どちらかのファイルにのみ存在する行と、その行がどちらのファイルに存在するかを出力したい
  • 2つのファイルがあり、両方に存在する行を出力したい

実際にやってみる

書いてもよくわからないし後で見たときによくわからないので実践。

id_num.txt と id_even.txt という2つのファイルを用意する
  • id_num.txt
% cat id_num.txt
1
2
3
4
5
  • id_even.txt
% cat id_even.txt
2
4
6

grepすればわかる通り、

  • 「1」「3」「5」はnumにだけ存在する
  • 「6」はevenにだけ存在する
  • 「2」と「4」は共通
commコマンドを(オプションなしで)実行するとタブ区切りで以下の出力がされる
% comm id_num.txt id_even.txt
1
		2
3
		4
5
	6

左から「1つめの引数のファイルだけに存在する行」「2つめの引数のファイルだけに存在する行」「両方のファイルに存在する行」となる

「表示したくないカラム番号」をオプションで渡す
  • id_num.txtだけに存在する行が欲しい(つまり、2番目と3番目のカラムを表示したくない)
% comm -23 id_num.txt id_even.txt
1
3
5
  • id_even.txtだけに存在する行が欲しい(つまり、1番目と3番目のカラムを表示したくない)
% comm -13 id_num.txt id_even.txt
6
  • 両方のファイルに存在する行が欲しい(つまり、1番目と2番目のカラムを表示したくない)
% comm -12 id_num.txt id_even.txt
2
4
(補足)大文字と小文字を区別したくない場合には「-i」を付ければ良い
% cat id_large.txt
A

% cat id_small.txt
a

% comm id_large.txt id_small.txt # 区別されているので別々に出力される
A
	a

% comm -i id_large.txt id_small.txt # 区別されないので「共通の行」として出力される
		A

ちなみに comm の由来と思われるもの

manを見ると

NAME
     comm -- select or reject lines common to two files

と書いてあるので「common」の略ですかね