Skip to content
Redaction

Redaction

Redaction

A redaction masks every match, leaving the fields it is told to keep where they stand. A kept field is written as a reference is written in a template - card:last4, ip:octet1-2, email:domain, or 0:last4 for the whole match - and must slice rather than transform, so upper is refused. The pattern’s guarded kinds decide what is masked: a run of digits is a card only under the Luhn check, so a number that only looks like one is left alone. The flags and parameters are on the CLI and PowerShell pages.

Mask and keep

$ trex redact '(\{card}:card | \I:ip | \E:email)' --keep 'card:last4, ip:octet1-2, email:domain' --text 'card 4111 1111 1111 1111 from 10.1.2.3 by bob@corp.example, ref 1234 5678 1234 5678'
card ***************1111 from 10.1**** by ****corp.example, ref 1234 5678 1234 5678

Each masked character becomes one *, so every offset and column after a match survives and a redacted log lines up with the one it came from.

Other masks

A mask of one character masks each character with it; a longer mask is a token each masked run becomes. Two words are masks that read the run: shape masks every letter as a and every digit as 0 and keeps every other byte, so the run keeps the shape its kind is recognized by and the redacted copy lexes as the original did; pseudonym replaces each distinct value with a stable name for its kind, numbered in order of first sight across the inputs of one run, so a value that recurred still recurs and @echo, the joins and templates read the redacted copy as they read the original. A declared shape or kind, and a library kind the pattern names, is named as its declaration names it: a customer shape’s values become CUSTOMER_1, CUSTOMER_2.

$ trex redact '\{card}:c' --keep c:last4 --mask '[card]' --text 'paid with 4111 1111 1111 1111 today'
paid with [card]1111 today

$ trex redact '\I' --mask shape --text 'from 10.4.5.6 and 10.9.9.9'
from 00.0.0.0 and 00.0.0.0

$ trex redact '\E' --mask shape --text 'user bob@x.com wrote'
user aaa@a.aaa wrote

$ trex redact '\I' --mask pseudonym --text 'from 10.4.5.6 to 10.9.9.9 and back to 10.4.5.6'
from IP_1 to IP_2 and back to IP_1

A pseudonym is one token to the lexer. Because the numbering follows the order values are first seen, a run under this mask reads its inputs in the order it walked them, so two runs of one command over one tree agree.

Files

One input is redacted to the standard output. --in-place, --dry-run, -C N, --lib, --shape, --hidden, --no-ignore and --binary work as they do for rewrite.

$ cat app.log
2026-09-27T09:00:04Z ERROR payment for bob@x.com failed: card 4111 1111 1111 1111 declined
2026-09-27T09:00:05Z INFO GET /v2/users from 10.0.0.5 took 95ms
$ trex redact '\{card}:c' --keep c:last4 app.log --dry-run
--- app.log
+++ app.log
@@ -1,2 +1,2 @@
-2026-09-27T09:00:04Z ERROR payment for bob@x.com failed: card 4111 1111 1111 1111 declined
+2026-09-27T09:00:04Z ERROR payment for bob@x.com failed: card ***************1111 declined
 2026-09-27T09:00:05Z INFO GET /v2/users from 10.0.0.5 took 95ms

Part of a file

--head N, --tail N and --lines A..B redact one window of each input; the window is printed alone, so nothing outside it reaches the output unmasked, and in place only the window changes. --follow redacts what a file gains as it grows.

$ trex redact '\E' app.log --head 1
2026-09-27T09:00:04Z ERROR payment for ********* failed: card 4111 1111 1111 1111 declined