join: Relational Join on a Common Field
join combines lines from two files that share a value in a common field, much like a database join.
When two files share a key column, join pairs their rows. Both files must be sorted on that key first.
What it does
join reads two files sorted on a join field (the first field by default) and outputs one line per matching pair, with the join field followed by the remaining fields of each file. -1 and -2 pick which field is the key in each file; -t sets the field separator; -a includes unmatched lines (an outer join).
Common usage
join users.txt roles.txt # join on field 1
join -t, -1 1 -2 2 a.csv b.csv # CSV, key is col1 of a, col2 of b
join -a1 -e NULL -o auto left.txt right.txt # left outer joinOptions
| Flag | What it does |
|---|---|
| -1 N / -2 N | Join field for file1 / file2 |
| -t <char> | Field separator (default: whitespace runs) |
| -a N | Also print unmatched lines from file N (outer join) |
| -e <str> | Replacement for empty output fields |
| -o <fmt> | Choose output fields, e.g. -o auto |
In CI
join is handy for combining two generated reports keyed on an ID. Critically, both files must be sorted on the join field with the same rules; sort -t, -k1,1 both inputs (and match join's -t) before joining.
Common errors in CI
"join: file 1 is not in sorted order" means the input is not sorted on the join field; sort it first with the same -t and key. A frequent subtle bug is sorting with a different separator or locale than join uses, so matching keys are skipped; keep -t and LC_ALL=C consistent across sort and join. Default field separation differs from sort -t behavior, so set -t explicitly on both.