Skip to content
Latchkey

awk match and substr: Extract Part of a Field

awk match(s, re) locates a regex in a string and sets RSTART and RLENGTH; substr(s, m, n) slices out a piece.

When the value you want is buried inside a field, like a version number in a tag, match plus substr extracts it without a separate tool.

What it does

match(string, regex) returns the position of the first match (0 if none) and sets RSTART to that position and RLENGTH to the match length. substr(string, start, length) returns a substring; start is 1-based and length is optional (rest of string if omitted).

Common usage

Terminal
# extract a semver from a tag like release-1.2.3
awk '{ if (match($0, /[0-9]+\.[0-9]+\.[0-9]+/))
         print substr($0, RSTART, RLENGTH) }' tags.txt
# first 7 chars of a commit SHA
awk '{print substr($1, 1, 7)}' commits.txt
# everything after the first colon
awk '{print substr($0, index($0, ":") + 1)}' kv.txt

Functions and variables

ItemWhat it does
match(s, /re/)Return match position (0 if none), set RSTART and RLENGTH
RSTARTStart position of the last match
RLENGTHLength of the last match (-1 if no match)
substr(s, m)Substring from position m to end (1-based)
substr(s, m, n)Substring of length n starting at position m
index(s, t)Position of substring t in s, or 0

In CI

match plus substr extracts a version or hash from messy tool output, which you can then push to $GITHUB_OUTPUT. Always guard substr with an if (match(...)) check so a non-matching line does not slice the wrong bytes.

Common errors in CI

awk string positions are 1-based, not 0-based; substr($0, 0, 3) behaves oddly because position 0 is before the string. When match fails, RLENGTH is -1, so substr($0, RSTART, RLENGTH) returns an empty or unexpected string; check the match return value first. Off-by-one slices usually come from forgetting the +1 after an index() position.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →