comm

Porównuje dwa posortowane pliki linia po linii, pokazując wspólne i unikalne linie.

comm to mała, ale bardzo sprytna komenda Uniksa, która porównuje dwa posortowane pliki linia po linii i mówi Ci trzy rzeczy naraz: co jest tylko w pierwszym pliku, co tylko w drugim, a co w obu. Wynik wyświetla w trzech kolumnach rozdzielonych tabulatorami. Idealne do szybkiej odpowiedzi na pytanie „czym różnią się te dwie listy?” bez odpalania całego diff. Haczyk jest jeden i fundamentalny: oba pliki muszą być wcześniej posortowane, inaczej dostaniesz bzdury.

Składnia i najważniejsze opcje

Podstawowe wywołanie wygląda tak: comm [opcje] plik1 plik2. Domyślnie dostajesz kolumnę 1 (tylko plik1), kolumnę 2 (tylko plik2) i kolumnę 3 (wspólne). Każda kolumna jest poprzedzona tabulatorami w liczbie równej liczbie wyświetlanych kolumn o niższym numerze.

  • -1 — ukrywa kolumnę 1 (linie tylko w plik1).
  • -2 — ukrywa kolumnę 2 (linie tylko w plik2).
  • -3 — ukrywa kolumnę 3 (linie wspólne).
  • -i — porównanie bez rozróżniania wielkości liter (case-insensitive).
  • --check-order / --nocheck-order — wymusza albo wyłącza kontrolę, czy pliki są posortowane (GNU coreutils).
  • --output-delimiter=STR — zamienia tabulatory na własny separator kolumn (GNU).
  • --total — dokłada na końcu wiersz z podsumowaniem liczb w każdej kolumnie (GNU).
  • - — w miejscu nazwy pliku oznacza standardowe wejście.

Przykłady użycia

  • comm plik1.txt plik2.txt — klasyka: trzy kolumny pokazujące unikalne i wspólne linie obu posortowanych plików.
  • comm -12 plik1.txt plik2.txt — zostawia tylko kolumnę 3, czyli pokazuje wyłącznie linie wspólne (część wspólna zbiorów).
  • comm -23 plik1.txt plik2.txt — pokazuje linie, które są tylko w plik1 i nie ma ich w plik2. Świetne do pytania „co usunięto?”.
  • comm -13 plik1.txt plik2.txt — odwrotnie: linie obecne tylko w plik2, czyli „co doszło?”.
  • comm -12 <(sort a.txt) <(sort b.txt) — sortowanie w locie przez process substitution, gdy pliki nie są jeszcze uporządkowane.

Częste błędy i pułapki

Najczęstszy zgon: niezasortowane pliki. comm nie sortuje za Ciebie i przy bałaganie zwróci losowo wyglądające wyniki. GNU ostrzeże komunikatem „file is not in sorted order”, BSD (macOS) zwykle przemilczy. Pamiętaj też, że sortowanie musi być w tym samym ustawieniu locale, w jakim porównujesz — wymieszanie LC_ALL=C sort ze zwykłym sort potrafi rozjechać kolejność. Druga pułapka to różnice między systemami: --output-delimiter, --total, -z i --check-order to dodatki GNU coreutils i na macOS (BSD) ich nie znajdziesz — tam masz w zasadzie tylko -123i. Uważaj na białe znaki i końcówki linii: spacja na końcu albo CRLF z Windowsa sprawi, że „identyczne” linie zostaną uznane za różne.

Powiązane komendy: diff (różnice z kontekstem), sort (przygotowanie wejścia), uniq (duplikaty w jednym pliku), join (łączenie po wspólnym kluczu), grep.