Usage

Unicode-aware word-level diff in practice — flags, examples, and a note on CJK segmentation.

Basic word diff

The simplest invocation: two files, output to stdout.

$ dwdiff a.txt b.txt

Inserted words are wrapped in {+...+}; deleted words in [-...-]. Common words pass through untouched. The bundled ICU 78.3 does the Unicode word-segmentation in the background.

Common flags

flageffect
-d <chars>Add <chars> to the delimiter set (treated as standalone words).
-w <chars>Override whitespace characters (default: ASCII whitespace).
-c <file>Read <file> as the "old" side; positional arg is "new".
-P, --punctuationTreat all Unicode punctuation as delimiters.
-i, --ignore-caseFold case while comparing (uses ICU casefold).
-s, --statisticsPrint word counts to stderr.
-1, --no-deletedSuppress deleted words.
-2, --no-insertedSuppress inserted words.
-3, --no-commonSuppress common words.
-A <algo>Diff algorithm: default, minimal, patience, histogram, myers.
--color / --no-colorColour markers (default: --color on tty).
--diff-inputRead a unified diff on stdin and re-format at the word level.

CJK and UTF-8

With the bundled ICU 78.3, dwdiff does Unicode-segmentation on CJK. The bundled ICU uses the UAX #29 grapheme cluster break rules and the UAX #14 line break rules. See cjk for a full worked example.

UTF-8 round-trip is preserved losslessly (the binary is UTF-8 native). Emoji, combining marks, and right-to-left text all pass through without corruption.

Re-formatting a unified diff

Pass an existing diff -u output to dwdiff --diff-input to re-format it at the word level. Useful for rendering a code review in a terminal-friendly way.

$ git diff | dwdiff --diff-input

Statistics

$ dwdiff -s a.txt b.txt
old: 7 words
new: 7 words  6 86% common  1 14% deleted  0 0% changed

Statistics go to stderr; the marked output goes to stdout. So dwdiff -s a.txt b.txt >/dev/null is a common pattern in shell scripts.