Skip to content

Version 0.6.3 (2026-10-21)

Choose a tag to compare

@github-actions github-actions released this 21 Oct 13:16

Release Notes

  • Add raw string literals, like Rust's: r"C:\Program Files\Rust" is taken verbatim, backslashes are not escapes (no more "\\d+" in dynamic regexes: $0 ~ r"\d+"). To include ", put the same number of #s around the quotes: r#"say "hi""#, r##"a"#b"##. A raw string can span lines. Behavior change: r"..." (no space) is now a raw string, not the variable r concatenated with a string; write r "..." for the latter
  • Add the ??= operator: l ??= r is l ?? (l = r), so r is evaluated and assigned only when l is uninitialized, empty or zero (as for ??); the subscript of an array element is evaluated once. E.g. { OFS ??= ","; total[$1] ??= 0 }
  • Add the !in operator, like Kotlin's !in (Python's not in): k !in arr is !(k in arr), e.g. $1 !in seen { seen[$1]; print }; multi-dimensional keys work too: (i, j) !in arr
  • Add key-value iteration for (k, v in arr) body, like Python's for k, v in d.items(): the same as for (k in arr) { v = arr[k]; body }, e.g. END { for (k, v in cnt) print k, v }; on an array made by split it works like enumerate. arr must be an array variable: for (k, v in f()) is a syntax error (assign the result first: a = f(); for (k, v in a))
  • Add negative field indexes: $(-k) is $(NF + 1 - k), so $(-1) is $NF and $(-2) is $(NF-1). Reading before the first field gives "", assigning there is a fatal error; the parentheses are required ($-1 is a syntax error)
  • Add assert(cond, msg): when cond is false, print msg to stderr and exit at once with code 2, without running END (unlike exit 2), e.g. { assert(NF == 5, f"line {NR}: expect 5 fields, got {NF}") }
  • Add local variables: { local a = $1; ... } declares a for the rest of the rule (or function body), including nested blocks; it shadows a global a, which other rules still see. A local is uninitialized again on each run of the rule ({ local n; n++; print n } prints 1 for every record), local arr[] is an empty array, and local x = x + 1 reads the outer x. Several can be declared at once (local i, s = "", seen[]). In a function, locals are new on each call, like the extra-parameter idiom. Special variables (NR, FS, SUBSEP, ...) and function names cannot be local, a name cannot be declared twice in one local statement, and a scalar local used as an array is an error that suggests local x[]. Behavior change: local is a keyword and can no longer be used as a variable or function name (local = 1 and function local() are now syntax errors); rename such variables or functions
  • A failing stdlib function (database, HTTP, KV, S3, crypto, ...) now also sets ERRNO to its message (e.g. sqlite_query: no such table: users), and a network error of http_get/http_post (status 0) sets ERRNO to the reason, so ERRNO = ""; r = sqlite_query(db, sql); if (ERRNO != "") ... tells a failure from an empty result
  • Database functions take optional positional parameters: sqlite_query/sqlite_execute, libsql_*, mysql_* and pg_* accept an array as a third argument, bound in key order to a prepared statement (p[1] = $1; p[2] = $2; sqlite_execute(db, "insert into t values(?, ?)", p)), so values containing ' work and input data cannot inject SQL. Placeholders are ? (SQLite, libSQL, MySQL) or $1, $2... (PostgreSQL); PostgreSQL converts the text values to the inferred parameter types (bool, integers, floats, numeric, json, uuid, inet, bytea, date/time), with an empty value as NULL for non-text types. PostgreSQL error messages now include the cause (db error: ERROR: relation "t" does not exist) instead of only db error
  • -i jsonl/-i json: a key missing from the first record is no longer dropped. It gets the next column when a later record has it (NF grows from that record on) and is added to FI, so $FI[k] with a key only known at run time finds it; a scalar first record no longer leaves the later objects with NF=0
  • Behavior change: s3_get/s3_put failures are a warning and an empty result, like other stdlib functions, instead of a fatal panic

Install zawk 0.6.3

Install prebuilt binaries via Homebrew

brew install zawk

Download zawk 0.6.3

File Platform Checksum
zawk-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
zawk-x86_64-apple-darwin.tar.xz Intel macOS checksum
zawk-x86_64-pc-windows-msvc.zip x64 Windows checksum
zawk-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
zawk-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum
zawk-aarch64-unknown-linux-musl.tar.xz ARM64 MUSL Linux checksum
zawk-x86_64-unknown-linux-musl.tar.xz x64 MUSL Linux checksum