awk Cheatsheet
Operators and Expressions
Use this awk reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Operator table, highest precedence first
| Operators | Notes |
|---|---|
$ | field reference, binds tighter than everything |
++ -- | prefix and postfix |
^ | exponentiation, right associative (2^3^2 is 512) |
! - + | unary |
* / % | % is fmod, so it works on non-integers |
+ - | addition |
| (nothing) | string concatenation, a b glues a and b |
< <= > >= != == | comparison, numeric or string (see below) |
~ !~ | regex match |
in | array membership |
&& | logical and, short-circuits |
|| | logical or, short-circuits |
?: | ternary, right associative |
= += -= *= /= %= ^= | assignment, right associative |
awk 'BEGIN{ print 2^3^2 }' # 512, not 64 awk 'BEGIN{ print 7 % 3, -7 % 3 }' # 1 -1 awk 'BEGIN{ print 10 % 3.5 }' # 3
Concatenation has no operator, and that hurts
Two expressions side by side concatenate. Since + binds tighter than
concatenation, and concatenation binds tighter than comparison, spacing is
cosmetic but grouping is not.
awk 'BEGIN{ print "a" 1+1 }' # a2 awk 'BEGIN{ print 1 " " 2 }' # 1 2 awk 'BEGIN{ print -1 " " -1 }' # -1-1 <-- (-1) then (" " - 1) awk 'BEGIN{ print 1 " " 2 - 1 }' # 1 1 <-- 1 then (" " 2) - 1 awk 'BEGIN{ print (1 == 1 "x") }' # 0 <-- 1 == "1x", a string compare awk 'BEGIN{ print (-1) " " (-1) }' # -1 -1 <-- what you meant
Wrap anything ambiguous in parentheses. The -1 " " -1 case is the one people
lose an hour to, the " " is eaten as the left operand of a subtraction.
String versus numeric comparison
The rule: a comparison is numeric only when both sides are numbers or look like numbers and came from the input. Otherwise it is a string comparison.
| Both sides | Comparison |
|---|---|
| number and number | numeric |
field / getline var / -v var / ARGV / ENVIRON that looks numeric | numeric ("strnum") |
| string constant, or result of concatenation | string |
awk 'BEGIN{ if ("10" < "9") print "string" }' # prints, "1" < "9" echo "10 9" | awk '{ if ($1 > $2) print "numeric" }' # prints, fields are strnum awk -v x=10 'BEGIN{ print (x > 9) }' # 1, -v values are strnum awk 'BEGIN{ x="10"; print (x == 10) }' # 1, the constant coerces
Force the comparison you want:
$1 + 0 == $2 + 0 # definitely numeric $1 "" == $2 "" # definitely string
Leading and trailing blanks and a
+sign still count as numeric, so the field10compares as 10. A field like10abcis not numeric, and10abc + 0is10.
Truthiness and uninitialized values
An uninitialized variable is both 0 and "" at once, and it is false.
awk 'BEGIN{ print x+0, "["x"]", length(x), (x?"t":"f") }' # 0 [] 0 f
| Value | Truthy? |
|---|---|
0, 0.0 | no |
"" | no |
| uninitialized | no |
"0" (string constant) | yes |
a field holding 0 | no, it is a strnum |
| any other non-empty string | yes |
That split is why if ($3) and if ($3 != "") behave differently on a column of
zeroes.
Increment, assignment, and the !seen[$0]++ idiom
Postfix ++ yields the old value, then increments. On an array element it also
creates the element.
# dedupe: first time seen[$0] is 0 (false), !0 is true, then it becomes 1 awk '!seen[$0]++' file # number only the duplicates awk '{ n = ++count[$1]; if (n > 1) print n, $0 }' file # compound assignment on a field rebuilds $0 printf '1 2\n' | awk '{ $1 *= 10; print }' # 10 2
Redirect versus greater-than
Inside print and printf, > means redirect to a file. There is no way for
awk to tell your comparison apart, so parenthesize it.
awk 'BEGIN{ print 1 > 2 }' # creates a file named "2" containing "1" awk 'BEGIN{ print (1 > 2) }' # prints 0 awk 'BEGIN{ x = 1 > 2; print x }' # fine, assignment context is unambiguous
The same trap applies to >> and |. >=, <, and == are safe, only > and
>> are overloaded.