Comparison expressions compare strings or numbers for relationships such as equality. They are written using relational operators, which are a superset of those in C. Table 6.3 describes them.
Expression | Result |
---|---|
x < y | True if x is less than y |
x <= y | True if x is less than or equal to y |
x > y | True if x is greater than y |
x >= y | True if x is greater than or equal to y |
x == y | True if x is equal to y |
x != y | True if x is not equal to y |
x ~ y | True if the string x matches the regexp denoted by y |
x !~ y | True if the string x does not match the regexp denoted by y |
subscript in array | True if the array array has an element with the subscript subscript |
Comparison expressions have the value one if true and zero if false.
When comparing operands of mixed types, numeric operands are converted
to strings using the value of CONVFMT
(see Conversion of Strings and Numbers).
Strings are compared
by comparing the first character of each, then the second character of each,
and so on. Thus, "10"
is less than "9"
. If there are two
strings where one is a prefix of the other, the shorter string is less than
the longer one. Thus, "abc"
is less than "abcd"
.
It is very easy to accidentally mistype the ‘==’ operator and
leave off one of the ‘=’ characters. The result is still valid
awk
code, but the program does not do what is intended:
if (a = b) # oops! should be a == b ... else ...
Unless b
happens to be zero or the null string, the if
part of the test always succeeds. Because the operators are
so similar, this kind of error is very difficult to spot when
scanning the source code.
The following list of expressions illustrates the kinds of comparisons
awk
performs, as well as what the result of each comparison is:
1.5 <= 2.0
Numeric comparison (true)
"abc" >= "xyz"
String comparison (false)
1.5 != " +2"
String comparison (true)
"1e2" < "3"
String comparison (true)
a = 2; b = "2"
a == b
String comparison (true)
a = 2; b = " +2"
a == b
String comparison (false)
In this example:
$ echo 1e2 3 | awk '{ print ($1 < $2) ? "true" : "false" }' -| false
the result is ‘false’ because both $1
and $2
are user input. They are numeric strings—therefore both have
the strnum attribute, dictating a numeric comparison.
The purpose of the comparison rules and the use of numeric strings is
to attempt to produce the behavior that is “least surprising,” while
still “doing the right thing.”
String comparisons and regular expression comparisons are very different. For example:
x == "foo"
has the value one, or is true if the variable x
is precisely ‘foo’. By contrast:
x ~ /foo/
has the value one if x
contains ‘foo’, such as
"Oh, what a fool am I!"
.
The righthand operand of the ‘~’ and ‘!~’ operators may be
either a regexp constant (/
…/
) or an ordinary
expression. In the latter case, the value of the expression as a string is used as a
dynamic regexp (see How to Use Regular Expressions; also
see Using Dynamic Regexps).
A constant regular
expression in slashes by itself is also an expression.
/regexp/
is an abbreviation for the following comparison expression:
$0 ~ /regexp/
One special place where /foo/
is not an abbreviation for
‘$0 ~ /foo/’ is when it is the righthand operand of ‘~’ or
‘!~’.
See Using Regular Expression Constants,
where this is discussed in more detail.