comm Command Cheat Sheet
comm compares two sorted files line by line. It is the standard tool for performing set operations (intersection, difference, union) on text files in the terminal.
Synopsis
comm [OPTION]... FILE1 FILE2
Description
comm reads FILE1 and FILE2 (which must be sorted) and produces output with three columns:
1. Lines only in FILE1
2. Lines only in FILE2
3. Lines in both files
If a file is not sorted, comm might complain or produce incorrect results.
Basic Usage
Compare Two Files
file1.txt:
apple
banana
cherry
file2.txt:
banana
date
elderberry
Command:
comm file1.txt file2.txt
Output:
apple
banana
date
elderberry
cherry
Correct Output for Example Above
apple
banana
cherry
date
elderberry
cherry is in file1 but not file2, it should be in col 1. If date is in file2 but not file1, col 2. banana in both, col 3).
Column Suppression (The Power of comm)
The most useful way to use comm is by suppressing columns you don't want.
| Option | Suppresses | Result |
|---|---|---|
-1 |
Column 1 | Show unique to FILE2 and common lines |
-2 |
Column 2 | Show unique to FILE1 and common lines |
-3 |
Column 3 | Show only unique lines (Difference) |
-12 |
Col 1 & 2 | Show intersection (only common lines) |
-13 |
Col 1 & 3 | Show lines only in FILE2 |
-23 |
Col 2 & 3 | Show lines only in FILE1 |
Practical Examples
Find lines common to both files (Intersection):
comm -12 file1.txt file2.txt
# Output: banana
Find lines in file1 but NOT in file2 (Difference):
comm -23 file1.txt file2.txt
# Output: apple, cherry
Find lines in file2 but NOT in file1:
comm -13 file1.txt file2.txt
# Output: date, elderberry
Print all unique lines from both files (Symmetric Difference):
comm -3 file1.txt file2.txt | sed 's/\t//g'
# Output: apple, cherry, date, elderberry
Advanced Usage
Sorting Inline
Since comm requires sorted input, you often use it with process substitution to sort on the fly.
comm -12 <(sort unsorted1.txt) <(sort unsorted2.txt)
Case Insensitive Comparison
Use sort -f (ignore case) inside the substitution, but comm lacks a native ignore-case flag in many versions (GNU comm has --nocheck-order but not case folding). Better to lowercase everything first if needed.
comm -12 <(tr 'A-Z' 'a-z' < file1 | sort) <(tr 'A-Z' 'a-z' < file2 | sort)
Changing Separator
By default, columns are separated by tabs. Use --output-delimiter to change this.
comm -12 --output-delimiter="," file1.txt file2.txt
Check Order
If you are unsure if files are sorted:
comm --check-order file1.txt file2.txt
Practical Scenarios
Compare Lists of Users
Find users who are in both the developers group and the admins group (assuming you have list files).
comm -12 dev_users.txt admin_users.txt
Validating a Migration
You migrated lines from a database.
1. Export source IDs to source.txt.
2. Export destination IDs to dest.txt.
3. Check for missing IDs:
comm -23 <(sort source.txt) <(sort dest.txt)
# Shows IDs that are in source but missing in dest
Server Inventory Check
Compare a list of expected packages vs installed packages.
comm -23 expected_packages.txt <(dpkg --get-selections | awk '{print $1}' | sort)
# Lists packages you expected but are NOT installed
comm vs diff
| Feature | comm | diff |
|---|---|---|
| Input Requirement | Must be sorted | Can be unsorted |
| Output Style | 3 Columns | Contextual patch format (<, >) |
| UseCase | Set logic (Intersection/Difference) | Content changes/Patching |
| Complexity | Simple filter | distinctive analysis |
Exit Status
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Error (usually unsorted input if checking enabled) |
Tips
- Always sort first!
commrelies entirely on lexical order. If "apple" comes after "banana" in your file, logic breaks. - Use
man commto check for--nocheck-orderif you want to force a comparison on unsorted files (results undefined though).