Declare an atom for one command
Declare a shape, a kind or a sub-pattern for the one command that reads it, with no pattern file. Each takes what a pattern file’s line says after its keyword, and each reads the declarations given before it.
$ cat ops.log
2026-09-27T09:00:01Z OPS-1234 opened for C00042 by ann
2026-09-27T09:05:12Z DB-77 linked to OPS-1234
2026-09-27T09:07:40Z OPS-1250 opened for C00077 by bob
2026-09-27T09:12:03Z OPS-1234 closed for C00042
A shape and a sub-pattern
--shape declares a token by its bytes, and --let a sub-pattern read in place of \{name},
its captures with it:
$ trex scan '\{ticket}:t "opened" "for" \W \{by}' --shape 'ticket = `[A-Z]{2,5}-\d{1,5}`' --let 'by = "by" \W:who' ops.log --format '${t} ${who}'
OPS-1234 ann
OPS-1250 bob
--shape-after declares a shape tried only where no built-in recognizer matched.
A kind
--kind declares a token made of the tokens a pattern matches: after the lex, each match fuses
into one token of the kind, so a table counts it whole:
$ trex tokens --text 'DB-77 linked to OPS-1234' --kind 'ticket = \W "-" \N'
[0..5] ticket "DB-77"
[6..12] word "linked"
[13..15] word "to"
[16..24] ticket "OPS-1234"
$ trex top '\{ticket}' '${0}' --kind 'ticket = \W "-" \N' ops.log
OPS-1234 3
DB-77 1
OPS-1250 1
A line from a pattern file
--declare takes a line as a pattern file writes it, a shape-after, test, fields or
rule line among them, so a line copied from a file works unchanged. It reads what a
--lib file before it declared:
$ cat tickets.trex
shape ticket = `[A-Z]{2,5}-\d{1,5}`
shape customer = `C\d{5}`
$ trex scan '\{opened}' --lib tickets.trex --declare 'kind opened = \{ticket} "opened" "for" \{customer}' ops.log
[21..47] "OPS-1234 opened for C00042"
[122..148] "OPS-1250 opened for C00077"
A refused declaration reads as the line refused in a pattern file, and as Python’s
lib.declare and PowerShell’s -Declaration refuse it:
$ trex scan '\{x}' --text 'a b' --kind 'x = ('
trex: line 1: pattern error at byte 1: expected ')'