How to Compare Two Sorted Text Files Line by Line in Linux Using the comm Command

While the standard diff utility is the most commonly known tool for contrasting differences between two text documents, it can generate complex, multi-chunk delta outputs that require careful interpretation. When working with structured lists—such as server inventories, database exports, user registries, IP allowlists, or package manifests—the POSIX-standard comm utility provides a far cleaner, three-column comparative model. The comm command reads two lexicographically sorted files line by line and separates entries into lines unique to the first file, lines unique to the second file, and lines shared identically by both.

Understanding the Three-Column Output Model

Unlike diff, which indicates insertions, deletions, and line modifications using symbols, comm generates clean tabular columns separated by tabs:

  • Column 1 (Leftmost): Contains lines that appear exclusively in the first specified file.
  • Column 2 (Middle, indented by one tab): Contains lines that appear exclusively in the second specified file.
  • Column 3 (Rightmost, indented by two tabs): Contains lines that exist identically in both files (the intersection).

Prerequisite: Lexicographical Sorting

The foundational requirement of the comm command is that both input files must be sorted according to system collation sequences (typically byte-order LC_ALL=C) before comparison. If files are unsorted, comm terminates with a warning or produces incomplete results.

To sort files prior to comparison, run the standard sort command:

sort -u servers_may.txt -o servers_may_sorted.txt
sort -u servers_june.txt -o servers_june_sorted.txt

Alternatively, using Bash process substitution, you can sort both files on the fly in memory without creating temporary intermediate files on disk:

comm <(sort listA.txt) <(sort listB.txt)

Suppressing Specific Columns Using Numerical Flags

The true power of comm lies in its suppression flags: -1, -2, and -3. Each flag suppresses its corresponding output column, allowing you to isolate exact mathematical set operations:

1. Finding Lines Unique to the First File (Set Difference A – B)

To isolate records that exist in the first file but were deleted or missing in the second file, suppress columns 2 and 3:

comm -23 listA_sorted.txt listB_sorted.txt

This outputs only Column 1 entries, left-aligned without tabs, making it ideal for auditing decommissioned servers or revoked user accounts.

2. Finding Lines Unique to the Second File (Set Difference B – A)

To identify newly added items present exclusively in the second file, suppress columns 1 and 3:

comm -13 listA_sorted.txt listB_sorted.txt

This filters out shared lines and first-file lines, leaving only newly introduced records.

3. Finding Common Lines (Set Intersection A ∩ B)

To extract entries that are shared identically between both files, suppress columns 1 and 2:

comm -12 listA_sorted.txt listB_sorted.txt

This outputs the exact intersection between two datasets, useful for identifying duplicate user accounts across systems or intersecting network address blocks.

Handling Case Sensitivity and Formatting

By default, comm operates under case-sensitive rules where uppercase letters precede lowercase characters in standard ASCII collation. If your data contains inconsistent capitalisation (e.g., email addresses), specify case-insensitive sorting or force collation:

comm -12 <(sort -f file1.txt) <(sort -f file2.txt)

To verify whether a file is already properly sorted without running sort first, supply the --check-order argument:

comm --check-order file1.txt file2.txt

If either file violates order sequence, comm flags the exact offending line number immediately, ensuring complete data validation in automated shell scripts.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.