awk Cheatsheet
Built-in Variables
Use this awk reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
The full table
Every one of these is a plain global you can read and, unless noted, assign.
| Variable | Default | Meaning |
|---|---|---|
NR | 0 | records read so far, across every input file |
NF | — | number of fields in the current record |
FNR | 0 | record number within the current file |
FS | " " | input field separator (a string, or a regex if longer than 1 char) |
OFS | " " | output field separator, used by print a, b and record rebuilds |
RS | "\n" | input record separator ("" means paragraph mode) |
ORS | "\n" | output record separator, appended by print |
FILENAME | "" | name of the file being read, empty in BEGIN |
SUBSEP | "\034" | key joiner for a[i,j] subscripts |
RSTART | 0 | start position of the last match(), 0 if it failed |
RLENGTH | -1 | length of the last match(), -1 if it failed |
CONVFMT | "%.6g" | format used when a number becomes a string |
OFMT | "%.6g" | format used when print outputs a number |
ARGC / ARGV | — | operand count and array, ARGV[0] is "awk" |
ENVIRON | — | the process environment, ENVIRON["HOME"] |
CONVFMT vs OFMT
Two different formats for two different moments, and mixing them up is a classic source of "why did my number lose digits".
# OFMT applies when print writes a number awk 'BEGIN{ OFMT="%.2f"; print 3.14159 }' # 3.14 # CONVFMT applies when a number is concatenated into a string awk 'BEGIN{ CONVFMT="%.2f"; x=3.14159; print x "" }' # 3.14
- Integers bypass both. awk 'BEGIN{OFMT="%.2f"; print 100}' prints 100.
- printf ignores both, its own format string wins. Use printf when the exact
digits matter.
Separator variables in practice
# comma in, tab out awk 'BEGIN{ FS=","; OFS="\t" } { $1=$1; print }' data.csv # one record per line in, comma-joined stream out awk 'BEGIN{ ORS="," } { print $1 } END{ printf "\n" }' data.txt # paragraph mode: blank-line-separated records awk 'BEGIN{ RS=""; FS="\n" } { print NR": "$1 }' notes.txt
Assigning
FSin a rule affects the next record. AssigningOFSorORStakes effect immediately, butOFSonly shows up once something rebuilds$0.
RSTART and RLENGTH
match(s, re) returns the start position and also sets these two, which is how
you extract a substring by regex in POSIX awk.
printf 'id=4711;\n' | awk '{ if (match($0, /[0-9]+/)) print substr($0, RSTART, RLENGTH) }' # 4711
On a failed match RSTART is 0 and RLENGTH is -1, so guard with the return
value rather than testing RSTART > 0 after the fact.
ARGV, ARGC, and ENVIRON
ARGV holds the operands, not the options. You can edit it in BEGIN to add or
drop files before any reading happens.
# list what awk thinks its inputs are awk 'BEGIN{ for (i=0; i<ARGC; i++) print i, ARGV[i] }' a.txt b.txt # 0 awk # 1 a.txt # 2 b.txt # read an env var without -v HOME_DIR=$HOME awk 'BEGIN{ print ENVIRON["HOME_DIR"] }'
Deleting an element of ARGV (or setting it to "") makes awk skip that file.
ENVIRON is POSIX and works in macOS awk, gawk, and mawk.
gawk-only variables
Do not reach for these in a script that has to run on macOS or a BSD.
| Variable | What it does |
|---|---|
RT | the text that actually matched RS on this record |
IGNORECASE | non-zero makes every regex and string compare case-blind |
FIELDWIDTHS | fixed-width parsing instead of FS |
FPAT | define fields by what they are, the sane CSV route |
PROCINFO | pid, uid, sorted_in, and more. Absent, not an error, on macOS awk |
ERRNO | message from a failed getline or close |
BINMODE / LINT / TEXTDOMAIN | I/O mode, warnings, i18n |
# gawk only: quoted CSV fields, the thing plain FS="," cannot do gawk -v FPAT='([^,]*)|("[^"]*")' '{ print NF, $2 }' quoted.csv # gawk only: deterministic iteration order gawk 'BEGIN{ PROCINFO["sorted_in"]="@ind_str_asc" } { c[$1]++ } END{ for (k in c) print k, c[k] }' data.txt
macOS awk silently treats IGNORECASE as an ordinary unused variable, so the
script runs and quietly does the wrong thing. That is worse than an error, test
your awk before relying on it.