gawk: Boolean Ops

 
 6.3.3 Boolean Expressions
 -------------------------
 
 A "Boolean expression" is a combination of comparison expressions or
 matching expressions, using the Boolean operators "or" ('||'), "and"
 ('&&'), and "not" ('!'), along with parentheses to control nesting.  The
 truth value of the Boolean expression is computed by combining the truth
 values of the component expressions.  Boolean expressions are also
 referred to as "logical expressions".  The terms are equivalent.
 
    Boolean expressions can be used wherever comparison and matching
 expressions can be used.  They can be used in 'if', 'while', 'do', and
 'for' statements (SeeStatements).  They have numeric values (one if
 true, zero if false) that come into play if the result of the Boolean
 expression is stored in a variable or used in arithmetic.
 
    In addition, every Boolean expression is also a valid pattern, so you
 can use one as a pattern to control the execution of rules.  The Boolean
 operators are:
 
 'BOOLEAN1 && BOOLEAN2'
      True if both BOOLEAN1 and BOOLEAN2 are true.  For example, the
      following statement prints the current input record if it contains
      both 'edu' and 'li':
 
           if ($0 ~ /edu/ && $0 ~ /li/) print
 
      The subexpression BOOLEAN2 is evaluated only if BOOLEAN1 is true.
      This can make a difference when BOOLEAN2 contains expressions that
      have side effects.  In the case of '$0 ~ /foo/ && ($2 == bar++)',
      the variable 'bar' is not incremented if there is no substring
      'foo' in the record.
 
 'BOOLEAN1 || BOOLEAN2'
      True if at least one of BOOLEAN1 or BOOLEAN2 is true.  For example,
      the following statement prints all records in the input that
      contain _either_ 'edu' or 'li':
 
           if ($0 ~ /edu/ || $0 ~ /li/) print
 
      The subexpression BOOLEAN2 is evaluated only if BOOLEAN1 is false.
      This can make a difference when BOOLEAN2 contains expressions that
      have side effects.  (Thus, this test never really distinguishes
      records that contain both 'edu' and 'li'--as soon as 'edu' is
      matched, the full test succeeds.)
 
 '! BOOLEAN'
      True if BOOLEAN is false.  For example, the following program
      prints 'no home!' in the unusual event that the 'HOME' environment
      variable is not defined:
 
           BEGIN { if (! ("HOME" in ENVIRON))
                       print "no home!" }
 
      (The 'in' operator is described in SeeReference to Elements.)
 
    The '&&' and '||' operators are called "short-circuit" operators
 because of the way they work.  Evaluation of the full expression is
 "short-circuited" if the result can be determined partway through its
 evaluation.
 
    Statements that end with '&&' or '||' can be continued simply by
 putting a newline after them.  But you cannot put a newline in front of
 either of these operators without using backslash continuation (See
 Statements/Lines).
 
    The actual value of an expression using the '!' operator is either
 one or zero, depending upon the truth value of the expression it is
 applied to.  The '!' operator is often useful for changing the sense of
 a flag variable from false to true and back again.  For example, the
 following program is one way to print lines in between special
 bracketing lines:
 
      $1 == "START"   { interested = ! interested; next }
      interested      { print }
      $1 == "END"     { interested = ! interested; next }
 
 The variable 'interested', as with all 'awk' variables, starts out
 initialized to zero, which is also false.  When a line is seen whose
 first field is 'START', the value of 'interested' is toggled to true,
 using '!'.  The next rule prints lines as long as 'interested' is true.
 When a line is seen whose first field is 'END', 'interested' is toggled
 back to false.(1)
 
    Most commonly, the '!' operator is used in the conditions of 'if' and
 'while' statements, where it often makes more sense to phrase the logic
 in the negative:
 
      if (! SOME CONDITION || SOME OTHER CONDITION) {
          ... DO WHATEVER PROCESSING ...
      }
 
      NOTE: The 'next' statement is discussed in SeeNext Statement.
      'next' tells 'awk' to skip the rest of the rules, get the next
      record, and start processing the rules over again at the top.  The
      reason it's there is to avoid printing the bracketing 'START' and
      'END' lines.
 
    ---------- Footnotes ----------
 
    (1) This program has a bug; it prints lines starting with 'END'.  How
 would you fix it?