Provided by: manpages-posix_2013a-1_all bug

PROLOG

       This  manual  page  is part of the POSIX Programmer's Manual.  The Linux implementation of
       this interface may differ (consult the corresponding Linux  manual  page  for  details  of
       Linux behavior), or the interface may not be implemented on Linux.

NAME

       awk — pattern scanning and processing language

SYNOPSIS

       awk [−F sepstring] [−v assignment]... program [argument...]

       awk [−F sepstring] −f progfile [−f progfile]... [−v assignment]...
            [argument...]

DESCRIPTION

       The  awk  utility shall execute programs written in the awk programming language, which is
       specialized for textual data manipulation. An awk program is a sequence  of  patterns  and
       corresponding  actions.  When  input is read that matches a pattern, the action associated
       with that pattern is carried out.

       Input shall be interpreted as a sequence of records. By default, a record is a line,  less
       its terminating <newline>, but this can be changed by using the RS built-in variable. Each
       record of input shall be matched in turn against each pattern in  the  program.  For  each
       pattern matched, the associated action shall be executed.

       The  awk  utility  shall  interpret  each  input  record as a sequence of fields where, by
       default, a field is a string of non-<blank> non-<newline> characters. This default <blank>
       and  <newline>  field delimiter can be changed by using the FS built-in variable or the −F
       sepstring option. The awk utility shall denote the first field in a record $1, the  second
       $2,  and  so  on.  The symbol $0 shall refer to the entire record; setting any other field
       causes the re-evaluation of $0. Assigning to $0 shall reset the values of all other fields
       and the NF built-in variable.

OPTIONS

       The  awk  utility  shall  conform  to the Base Definitions volume of POSIX.1‐2008, Section
       12.2, Utility Syntax Guidelines.

       The following options shall be supported:

       −F sepstring
                 Define the input field separator. This option shall be equivalent to:

                     -v FS=sepstring

                 except that if −F sepstring and −v FS=sepstring are both used, it is unspecified
                 whether  the  FS  assignment resulting from −F sepstring is processed in command
                 line order or is processed after the last −v FS=sepstring.  See the  description
                 of  the  FS  built-in  variable, and how it is used, in the EXTENDED DESCRIPTION
                 section.

       −f progfile
                 Specify the pathname of the file progfile containing an awk program. A  pathname
                 of '−' shall denote the standard input. If multiple instances of this option are
                 specified, the concatenation of the files specified as  progfile  in  the  order
                 specified  shall  be  the  awk  program.  The  awk  program can alternatively be
                 specified in the command line as a single argument.

       −v assignment
                 The application shall ensure that the assignment argument is in the same form as
                 an  assignment  operand.  The specified variable assignment shall occur prior to
                 executing the awk program, including the actions associated with BEGIN  patterns
                 (if any). Multiple occurrences of this option can be specified.

OPERANDS

       The following operands shall be supported:

       program   If  no −f option is specified, the first operand to awk shall be the text of the
                 awk program. The application shall  supply  the  program  operand  as  a  single
                 argument  to  awk.  If the text does not end in a <newline>, awk shall interpret
                 the text as if it did.

       argument  Either of the following two types of argument can be intermixed:

                 file      A pathname of a file that contains the input  to  be  read,  which  is
                           matched  against  the  set  of  patterns  in  the  program. If no file
                           operands are specified, or if a file  operand  is  '−',  the  standard
                           input shall be used.

                 assignment
                           An  operand  that  begins with an <underscore> or alphabetic character
                           from the portable character set (see the table in the Base Definitions
                           volume of POSIX.1‐2008, Section 6.1, Portable Character Set), followed
                           by a  sequence  of  underscores,  digits,  and  alphabetics  from  the
                           portable character set, followed by the '=' character, shall specify a
                           variable assignment rather than a pathname.  The characters before the
                           '='  represent  the  name  of  an awk variable; if that name is an awk
                           reserved word (see Grammar) the behavior is undefined. The  characters
                           following  the  <equals-sign> shall be interpreted as if they appeared
                           in the awk program preceded  and  followed  by  a  double-quote  ('"')
                           character,  as  a  STRING token (see Grammar), except that if the last
                           character is an unescaped <backslash>, it shall be  interpreted  as  a
                           literal <backslash> rather than as the first character of the sequence
                           "\"".  The variable shall be assigned the value of that  STRING  token
                           and,  if  appropriate,  shall  be  considered  a  numeric  string (see
                           Expressions in awk), the variable shall also be assigned  its  numeric
                           value.  Each  such  variable  assignment shall occur just prior to the
                           processing of the following file, if any. Thus, an  assignment  before
                           the  first file argument shall be executed after the BEGIN actions (if
                           any), while an assignment after the last  file  argument  shall  occur
                           before  the  END  actions  (if  any).  If there are no file arguments,
                           assignments shall be executed before processing the standard input.

STDIN

       The standard input shall be used only if no file operands are  specified,  or  if  a  file
       operand  is  '−', or if a progfile option-argument is '−'; see the INPUT FILES section. If
       the awk program contains no actions and no patterns, but is otherwise a valid awk program,
       standard  input  and  any file operands shall not be read and awk shall exit with a return
       status of zero.

INPUT FILES

       Input files to the awk program from any of the following sources shall be text files:

        *  Any file operands or their equivalents, achieved by modifying the awk  variables  ARGV
           and ARGC

        *  Standard input in the absence of any file operands

        *  Arguments to the getline function

       Whether  the variable RS is set to a value other than a <newline> or not, for these files,
       implementations shall support records  terminated  with  the  specified  separator  up  to
       {LINE_MAX} bytes and may support longer records.

       If  −f progfile is specified, the application shall ensure that the files named by each of
       the progfile option-arguments are text files and their concatenation, in the same order as
       they appear in the arguments, is an awk program.

ENVIRONMENT VARIABLES

       The following environment variables shall affect the execution of awk:

       LANG      Provide a default value for the internationalization variables that are unset or
                 null.  (See  the  Base  Definitions  volume  of   POSIX.1‐2008,   Section   8.2,
                 Internationalization   Variables  for  the  precedence  of  internationalization
                 variables used to determine the values of locale categories.)

       LC_ALL    If set to a non-empty string  value,  override  the  values  of  all  the  other
                 internationalization variables.

       LC_COLLATE
                 Determine the locale for the behavior of ranges, equivalence classes, and multi-
                 character collating elements within regular expressions and  in  comparisons  of
                 string values.

       LC_CTYPE  Determine  the  locale for the interpretation of sequences of bytes of text data
                 as characters (for example, single-byte as opposed to multi-byte  characters  in
                 arguments  and  input  files),  the behavior of character classes within regular
                 expressions, the identification of characters as letters,  and  the  mapping  of
                 uppercase and lowercase characters for the toupper and tolower functions.

       LC_MESSAGES
                 Determine  the  locale  that should be used to affect the format and contents of
                 diagnostic messages written to standard error.

       LC_NUMERIC
                 Determine the radix character used when interpreting numeric  input,  performing
                 conversions  between  numeric  and string values, and formatting numeric output.
                 Regardless of locale, the <period> character (the decimal-point character of the
                 POSIX  locale)  is  the  decimal-point  character  recognized  in processing awk
                 programs (including assignments in command line arguments).

       NLSPATH   Determine the location of message catalogs for the processing of LC_MESSAGES.

       PATH      Determine the search path when looking for commands executed by system(expr), or
                 input and output pipes; see the Base Definitions volume of POSIX.1‐2008, Chapter
                 8, Environment Variables.

       In addition, all environment variables shall be visible via the awk variable ENVIRON.

ASYNCHRONOUS EVENTS

       Default.

STDOUT

       The nature of the output files depends on the awk program.

STDERR

       The standard error shall be used only for diagnostic messages.

OUTPUT FILES

       The nature of the output files depends on the awk program.

EXTENDED DESCRIPTION

   Overall Program Structure
       An awk program is composed of pairs of the form:

           pattern { action }

       Either the pattern or the  action  (including  the  enclosing  brace  characters)  can  be
       omitted.

       A  missing  pattern  shall  match  any  record  of  input,  and  a missing action shall be
       equivalent to:

           { print }

       Execution of the awk program shall start by first executing the  actions  associated  with
       all  BEGIN  patterns  in  the  order they occur in the program. Then each file operand (or
       standard input if no files were specified) shall be processed in turn by reading data from
       the  file  until  a  record  separator  is  seen  (<newline> by default). Before the first
       reference to a field in the record is evaluated, the record shall be  split  into  fields,
       according  to  the rules in Regular Expressions, using the value of FS that was current at
       the time the record was read. Each pattern in the program then shall be evaluated  in  the
       order  of occurrence, and the action associated with each pattern that matches the current
       record executed. The action for a matching pattern shall  be  executed  before  evaluating
       subsequent  patterns.  Finally,  the  actions  associated  with  all END patterns shall be
       executed in the order they occur in the program.

   Expressions in awk
       Expressions describe computations used in patterns and actions.  In the  following  table,
       valid  expression  operations  are given in groups from highest precedence first to lowest
       precedence last, with equal-precedence operators  grouped  between  horizontal  lines.  In
       expression  evaluation,  where  the  grammar  is  formally  ambiguous,  higher  precedence
       operators shall be evaluated before lower precedence operators. In this table expr, expr1,
       expr2,  and expr3 represent any expression, while lvalue represents any entity that can be
       assigned to (that is, on the left side of an assignment operator).  The precise syntax  of
       expressions is given in Grammar.

                         Table 4-1: Expressions in Decreasing Precedence in awk

            ┌─────────────────────┬─────────────────────────┬────────────────┬──────────────┐
            │       SyntaxNameType of ResultAssociativity │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │( expr )             │Grouping                 │Type of expr    │N/A           │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │$expr                │Field reference          │String          │N/A           │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │lvalue ++            │Post-increment           │Numeric         │N/A           │
            │lvalue −−            │Post-decrement           │Numeric         │N/A           │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │++ lvalue            │Pre-increment            │Numeric         │N/A           │
            │−− lvalue            │Pre-decrement            │Numeric         │N/A           │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │expr ^ expr          │Exponentiation           │Numeric         │Right         │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │! expr               │Logical not              │Numeric         │N/A           │
            │+ expr               │Unary plus               │Numeric         │N/A           │
            │− expr               │Unary minus              │Numeric         │N/A           │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │expr * expr          │Multiplication           │Numeric         │Left          │
            │expr / expr          │Division                 │Numeric         │Left          │
            │expr % expr          │Modulus                  │Numeric         │Left          │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │expr + expr          │Addition                 │Numeric         │Left          │
            │exprexpr          │Subtraction              │Numeric         │Left          │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │expr expr            │String concatenation     │String          │Left          │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │expr < expr          │Less than                │Numeric         │None          │
            │expr <= expr         │Less than or equal to    │Numeric         │None          │
            │expr != expr         │Not equal to             │Numeric         │None          │
            │expr == expr         │Equal to                 │Numeric         │None          │
            │expr > expr          │Greater than             │Numeric         │None          │
            │expr >= expr         │Greater than or equal to │Numeric         │None          │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │expr ~ expr          │ERE match                │Numeric         │None          │
            │expr !~ expr         │ERE non-match            │Numeric         │None          │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │expr in array        │Array membership         │Numeric         │Left          │
            │( index ) in array   │Multi-dimension array    │Numeric         │Left          │
            │                     │membership               │                │              │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │expr && expr         │Logical AND              │Numeric         │Left          │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │expr || expr         │Logical OR               │Numeric         │Left          │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │expr1 ? expr2 : expr3│Conditional expression   │Type of selected│Right         │
            │                     │                         │expr2 or expr3  │              │
            ├─────────────────────┼─────────────────────────┼────────────────┼──────────────┤
            │lvalue ^= expr       │Exponentiation assignment│Numeric         │Right         │
            │lvalue %= expr       │Modulus assignment       │Numeric         │Right         │
            │lvalue *= expr       │Multiplication assignment│Numeric         │Right         │
            │lvalue /= expr       │Division assignment      │Numeric         │Right         │
            │lvalue += expr       │Addition assignment      │Numeric         │Right         │
            │lvalue −= expr       │Subtraction assignment   │Numeric         │Right         │
            │lvalue = expr        │Assignment               │Type of expr    │Right         │
            └─────────────────────┴─────────────────────────┴────────────────┴──────────────┘
       Each  expression  shall  have  either  a string value, a numeric value, or both. Except as
       stated for specific contexts, the value of an expression shall be implicitly converted  to
       the  type needed for the context in which it is used. A string value shall be converted to
       a numeric value either by the equivalent of the following calls to  functions  defined  by
       the ISO C standard:

           setlocale(LC_NUMERIC, "");
           numeric_value = atof(string_value);

       or  by  converting  the  initial  portion  of  the string to type double representation as
       follows:

              The input string is decomposed into two parts: an initial, possibly empty, sequence
              of  white-space  characters  (as  specified  by  isspace())  and a subject sequence
              interpreted as a floating-point constant.

              The expected form of the subject sequence is an optional '+' or '−'  sign,  then  a
              non-empty  sequence  of  digits  optionally containing a <period>, then an optional
              exponent part. An exponent part consists of 'e' or 'E',  followed  by  an  optional
              sign, followed by one or more decimal digits.

              The sequence starting with the first digit or the <period> (whichever occurs first)
              is interpreted as a floating constant of the C language, and if neither an exponent
              part  nor a <period> appears, a <period> is assumed to follow the last digit in the
              string. If the subject sequence begins with a minus-sign, the value resulting  from
              the conversion is negated.

       A  numeric  value  that  is  exactly  equal to the value of an integer (see Section 1.1.2,
       Concepts Derived from the ISO C Standard) shall be converted to a string by the equivalent
       of  a  call to the sprintf function (see String Functions) with the string "%d" as the fmt
       argument and the numeric value being converted as the first and only  expr  argument.  Any
       other  numeric  value  shall  be  converted to a string by the equivalent of a call to the
       sprintf function with the value of the variable  CONVFMT  as  the  fmt  argument  and  the
       numeric  value  being  converted  as  the  first and only expr argument. The result of the
       conversion is unspecified  if  the  value  of  CONVFMT  is  not  a  floating-point  format
       specification.  This  volume  of  POSIX.1‐2008  specifies  no explicit conversions between
       numbers and strings. An application can force an expression to be treated as a  number  by
       adding  zero  to  it,  or can force it to be treated as a string by concatenating the null
       string ("") to it.

       A string value shall be considered a numeric string if it comes from one of the following:

        1. Field variables

        2. Input from the getline() function

        3. FILENAME

        4. ARGV array elements

        5. ENVIRON array elements

        6. Array elements created by the split() function

        7. A command line variable assignment

        8. Variable assignment from another numeric string variable

       and an implementation-dependent condition corresponding to either case (a) or (b) below is
       met.

        a. After  the  equivalent  of  the  following  calls  to  functions  defined by the ISO C
           standard, string_value_end would differ from string_value, and any  characters  before
           the terminating null character in string_value_end would be <blank> characters:

               char *string_value_end;
               setlocale(LC_NUMERIC, "");
               numeric_value = strtod (string_value, &string_value_end);

        b. After  all  the  following  conversions  have been applied, the resulting string would
           lexically be recognized as a NUMBER token as described by the lexical  conventions  in
           Grammar:

           --  All leading and trailing <blank> characters are discarded.

           --  If the first non-<blank> is '+' or '−', it is discarded.

           --  Each  occurrence of the decimal point character from the current locale is changed
               to a <period>.
       In case (a) the numeric value of the numeric string shall  be  the  value  that  would  be
       returned  by  the  strtod() call. In case (b) if the first non-<blank> is '−', the numeric
       value of the numeric string shall be the negation of the numeric value of  the  recognized
       NUMBER  token;  otherwise,  the  numeric  value of the numeric string shall be the numeric
       value of the recognized NUMBER token. Whether or not a string is a numeric string shall be
       relevant only in contexts where that term is used in this section.

       When  an  expression  is  used in a Boolean context, if it has a numeric value, a value of
       zero shall be treated as false and any other value shall be treated as true. Otherwise,  a
       string  value  of  the  null string shall be treated as false and any other value shall be
       treated as true.  A Boolean context shall be one of the following:

        *  The first subexpression of a conditional expression

        *  An expression operated on by logical NOT, logical AND, or logical OR

        *  The second expression of a for statement

        *  The expression of an if statement

        *  The expression of the while clause in either a while or do...while statement

        *  An expression used as a pattern (as in Overall Program Structure)

       All arithmetic shall follow the semantics of floating-point arithmetic as specified by the
       ISO C standard (see Section 1.1.2, Concepts Derived from the ISO C Standard).

       The value of the expression:

           expr1 ^ expr2

       shall be equivalent to the value returned by the ISO C standard function call:

           pow(expr1, expr2)

       The expression:

           lvalue ^= expr

       shall be equivalent to the ISO C standard expression:

           lvalue = pow(lvalue, expr)

       except that lvalue shall be evaluated only once. The value of the expression:

           expr1 % expr2

       shall be equivalent to the value returned by the ISO C standard function call:

           fmod(expr1, expr2)

       The expression:

           lvalue %= expr

       shall be equivalent to the ISO C standard expression:

           lvalue = fmod(lvalue, expr)

       except that lvalue shall be evaluated only once.

       Variables and fields shall be set by the assignment statement:

           lvalue = expression

       and  the  type  of  expression shall determine the resulting variable type. The assignment
       includes the arithmetic assignments ("+=", "−=", "*=", "/=", "%=", "^=", "++",  "−−")  all
       of  which  shall  produce  a  numeric  result. The left-hand side of an assignment and the
       target of increment and decrement operators can be one of a variable, an array with index,
       or a field selector.

       The  awk  language  supplies  arrays that are used for storing numbers or strings.  Arrays
       need not be declared. They  shall  initially  be  empty,  and  their  sizes  shall  change
       dynamically.  The  subscripts,  or  element  identifiers, are strings, providing a type of
       associative array capability. An array name followed by a subscript within square brackets
       can  be  used  as  an  lvalue  and thus as an expression, as described in the grammar; see
       Grammar.  Unsubscripted array names can be used in only the following contexts:

        *  A parameter in a function definition or function call

        *  The NAME token following any use of the keyword in as specified in  the  grammar  (see
           Grammar);  if  the  name  used  in  this context is not an array name, the behavior is
           undefined

       A valid array index shall consist of one or more <comma>-separated expressions, similar to
       the  way  in  which  multi-dimensional  arrays  are indexed in some programming languages.
       Because awk arrays are really one-dimensional, such  a  <comma>-separated  list  shall  be
       converted  to  a  single  string  by  concatenating  the  string  values  of  the separate
       expressions, each separated from the other by the value of the SUBSEP variable. Thus,  the
       following two index operations shall be equivalent:

           var[expr1, expr2, ... exprn]

           var[expr1 SUBSEP expr2 SUBSEP ... SUBSEP exprn]

       The  application  shall ensure that a multi-dimensioned index used with the in operator is
       parenthesized. The in operator, which tests  for  the  existence  of  a  particular  array
       element, shall not cause that element to exist. Any other reference to a nonexistent array
       element shall automatically create it.

       Comparisons (with the '<', "<=", "!=", "==",  '>',  and  ">="  operators)  shall  be  made
       numerically  if  both  operands  are numeric, if one is numeric and the other has a string
       value that is a numeric string, or if one is numeric and the other has  the  uninitialized
       value.   Otherwise,  operands  shall  be  converted  to  strings  as required and a string
       comparison shall be made using the locale-specific collation sequence. The  value  of  the
       comparison expression shall be 1 if the relation is true, or 0 if the relation is false.

   Variables and Special Variables
       Variables  can  be  used  in  an  awk  program  by referencing them. With the exception of
       function parameters (see  User-Defined  Functions),  they  are  not  explicitly  declared.
       Function parameter names shall be local to the function; all other variable names shall be
       global. The same name shall not be used as both a function parameter name and as the  name
       of  a  function  or  a  special  awk  variable.  The same name shall not be used both as a
       variable name with global scope and as the name of a function. The same name shall not  be
       used  within  the  same  scope  both  as a scalar variable and as an array.  Uninitialized
       variables, including scalar variables, array elements, and field variables, shall have  an
       uninitialized  value. An uninitialized value shall have both a numeric value of zero and a
       string value of the empty string. Evaluation of variables with an uninitialized value,  to
       either string or numeric, shall be determined by the context in which they are used.

       Field variables shall be designated by a '$' followed by a number or numerical expression.
       The effect of the field number expression evaluating to anything other than a non-negative
       integer  is unspecified; uninitialized variables or string values need not be converted to
       numeric values in this context. New field variables can be created by assigning a value to
       them.  References to nonexistent fields (that is, fields after $NF), shall evaluate to the
       uninitialized value. Such references shall not create new fields. However, assigning to  a
       nonexistent  field  (for  example,  $(NF+2)=5)  shall increase the value of NF; create any
       intervening fields with the  uninitialized  value;  and  cause  the  value  of  $0  to  be
       recomputed,  with  the  fields  being  separated by the value of OFS.  Each field variable
       shall have a string value or an uninitialized value when created.  Field  variables  shall
       have  the  uninitialized  value  when  created  from $0 using FS and the variable does not
       contain any characters. If appropriate, the field variable shall be considered  a  numeric
       string (see Expressions in awk).

       Implementations shall support the following other special variables that are set by awk:

       ARGC      The number of elements in the ARGV array.

       ARGV      An  array of command line arguments, excluding options and the program argument,
                 numbered from zero to ARGC−1.

                 The arguments in ARGV can be modified or added to; ARGC can be altered. As  each
                 input  file  ends,  awk shall treat the next non-null element of ARGV, up to the
                 current value of ARGC−1, inclusive, as the name of the next  input  file.  Thus,
                 setting  an  element  of  ARGV  to null means that it shall not be treated as an
                 input file. The name '−' indicates the standard input. If  an  argument  matches
                 the  format  of  an  assignment  operand,  this  argument shall be treated as an
                 assignment rather than a file argument.

       CONVFMT   The  printf  format  for  converting  numbers  to  strings  (except  for  output
                 statements, where OFMT is used); "%.6g" by default.

       ENVIRON   An  array  representing  the  value of the environment, as described in the exec
                 functions defined in the System Interfaces volume of POSIX.1‐2008.  The  indices
                 of  the  array  shall  be  strings  consisting  of  the names of the environment
                 variables, and the value of each array element shall be a string  consisting  of
                 the  value  of  that variable. If appropriate, the environment variable shall be
                 considered a numeric string (see Expressions in awk); the  array  element  shall
                 also have its numeric value.

                 In  all  cases  where  the  behavior of awk is affected by environment variables
                 (including the environment of any commands that  awk  executes  via  the  system
                 function  or  via  pipeline  redirections  with  the print statement, the printf
                 statement,  or  the  getline  function),  the  environment  used  shall  be  the
                 environment  at  the  time  awk  began  executing;  it is implementation-defined
                 whether any modification of ENVIRON affects this environment.

       FILENAME  A pathname of the current input  file.  Inside  a  BEGIN  action  the  value  is
                 undefined.  Inside  an  END action the value shall be the name of the last input
                 file processed.

       FNR       The ordinal number of the current record in the current  file.  Inside  a  BEGIN
                 action  the  value  shall  be  zero. Inside an END action the value shall be the
                 number of the last record processed in the last file processed.

       FS        Input field separator regular expression; a <space> by default.

       NF        The number of fields in the current record. Inside a BEGIN action, the use of NF
                 is  undefined  unless  a  getline  function  without  a var argument is executed
                 previously. Inside an END action, NF shall retain the value it had for the  last
                 record  read,  unless  a  subsequent, redirected, getline function without a var
                 argument is performed prior to entering the END action.

       NR        The ordinal number of the current record from the  start  of  input.   Inside  a
                 BEGIN  action  the  value shall be zero. Inside an END action the value shall be
                 the number of the last record processed.

       OFMT      The printf format for converting numbers to strings in  output  statements  (see
                 Output  Statements);  "%.6g"  by  default.  The  result  of  the  conversion  is
                 unspecified if the value of OFMT is not a floating-point format specification.

       OFS       The print statement output field separator; <space> by default.

       ORS       The print statement output record separator; a <newline> by default.

       RLENGTH   The length of the string matched by the match function.

       RS        The first character of the  string  value  of  RS  shall  be  the  input  record
                 separator;  a  <newline> by default. If RS contains more than one character, the
                 results are unspecified. If RS is null, then records are separated by  sequences
                 consisting  of  a  <newline>  plus  one or more blank lines, leading or trailing
                 blank lines shall not result in empty records at the beginning  or  end  of  the
                 input,  and  a  <newline>  shall always be a field separator, no matter what the
                 value of FS is.

       RSTART    The starting position of the string matched by  the  match  function,  numbering
                 from  1.  This  shall  always  be  equivalent  to  the return value of the match
                 function.

       SUBSEP    The subscript separator string for multi-dimensional arrays; the  default  value
                 is implementation-defined.

   Regular Expressions
       The  awk  utility shall make use of the extended regular expression notation (see the Base
       Definitions volume of POSIX.1‐2008, Section 9.4, Extended Regular Expressions) except that
       it  shall  allow  the use of C-language conventions for escaping special characters within
       the EREs, as specified in the table  in  the  Base  Definitions  volume  of  POSIX.1‐2008,
       Chapter  5,  File Format Notation ('\\', '\a', '\b', '\f', '\n', '\r', '\t', '\v') and the
       following table; these escape sequences  shall  be  recognized  both  inside  and  outside
       bracket  expressions.  Note that records need not be separated by <newline> characters and
       string constants can contain <newline> characters, so even the "\n" sequence is  valid  in
       awk  EREs.  Using  a  <slash>  character  within an ERE requires the escaping shown in the
       following table.

                                   Table 4-2: Escape Sequences in awk

          ┌─────────┬────────────────────────────────────┬────────────────────────────────────┐
          │ Escape  │                                    │                                    │
          │SequenceDescriptionMeaning               │
          ├─────────┼────────────────────────────────────┼────────────────────────────────────┤
          │\"       │ <backslash> <quotation-mark>       │ <quotation-mark> character         │
          ├─────────┼────────────────────────────────────┼────────────────────────────────────┤
          │\/       │ <backslash> <slash>                │ <slash> character                  │
          ├─────────┼────────────────────────────────────┼────────────────────────────────────┤
          │\ddd     │ A <backslash> character followed   │ The character whose encoding is    │
          │         │ by the longest sequence of one,    │ represented by the one, two, or    │
          │         │ two, or three octal-digit          │ three-digit octal integer. Multi-  │
          │         │ characters (01234567). If all of   │ byte characters require multiple,  │
          │         │ the digits are 0 (that is,         │ concatenated escape sequences of   │
          │         │ representation of the NUL          │ this type, including the leading   │
          │         │ character), the behavior is        │ <backslash> for each byte.         │
          │         │ undefined.                         │                                    │
          ├─────────┼────────────────────────────────────┼────────────────────────────────────┤
          │\c       │ A <backslash> character followed   │ Undefined                          │
          │         │ by any character not described in  │                                    │
          │         │ this table or in the table in the  │                                    │
          │         │ Base Definitions volume of         │                                    │
          │         │ POSIX.1‐2008, Chapter 5, File      │                                    │
          │         │ Format Notation ('\\', '\a', '\b', │                                    │
          │         │ '\f', '\n', '\r', '\t', '\v').     │                                    │
          └─────────┴────────────────────────────────────┴────────────────────────────────────┘
       A regular expression can be matched against a specific field or string by using one of the
       two regular expression matching operators, '~' and "!~".  These operators shall  interpret
       their  right-hand operand as a regular expression and their left-hand operand as a string.
       If the regular expression matches the string, the '~' expression shall evaluate to a value
       of  1,  and  the  "!~"  expression shall evaluate to a value of 0. (The regular expression
       matching operation is as defined by the term matched in the  Base  Definitions  volume  of
       POSIX.1‐2008,  Section  9.1,  Regular  Expression Definitions, where a match occurs on any
       part of the string unless the regular expression  is  limited  with  the  <circumflex>  or
       <dollar-sign>  special  characters.)  If the regular expression does not match the string,
       the '~' expression shall evaluate to a value of 0, and the "!~" expression shall  evaluate
       to  a value of 1. If the right-hand operand is any expression other than the lexical token
       ERE, the string value of the expression  shall  be  interpreted  as  an  extended  regular
       expression, including the escape conventions described above.  Note that these same escape
       conventions shall also be applied in determining  the  value  of  a  string  literal  (the
       lexical  token  STRING),  and thus shall be applied a second time when a string literal is
       used in this context.

       When an ERE token appears as an expression in any context other than as the right-hand  of
       the '~' or "!~" operator or as one of the built-in function arguments described below, the
       value of the resulting expression shall be the equivalent of:

           $0  " "  /ere/

       The ere argument to the gsub, match, sub functions, and  the  fs  argument  to  the  split
       function  (see  String  Functions)  shall  be interpreted as extended regular expressions.
       These can be either ERE tokens or arbitrary expressions, and shall be interpreted  in  the
       same manner as the right-hand side of the '~' or "!~" operator.

       An  extended  regular  expression  can  be  used  to separate fields by assigning a string
       containing the expression to the built-in variable FS, either directly or as a consequence
       of  using the −F sepstring option.  The default value of the FS variable shall be a single
       <space>.  The following describes FS behavior:

        1. If FS is a null string, the behavior is unspecified.

        2. If FS is a single character:

            a. If FS is <space>, skip leading and  trailing  <blank>  and  <newline>  characters;
               fields shall be delimited by sets of one or more <blank> or <newline> characters.

            b. Otherwise,  if  FS  is  any  other  character c, fields shall be delimited by each
               single occurrence of c.

        3. Otherwise, the string value of FS shall  be  considered  to  be  an  extended  regular
           expression.  Each  occurrence  of  a sequence matching the extended regular expression
           shall delimit fields.

       Except for the '~' and "!~" operators, and in the gsub, match,  split,  and  sub  built-in
       functions,  ERE  matching  shall  be  based  on  input  records; that is, record separator
       characters (the first character of the value of the variable  RS,  <newline>  by  default)
       cannot  be  embedded in the expression, and no expression shall match the record separator
       character. If the record separator is not <newline>, <newline> characters embedded in  the
       expression  can  be  matched.  For  the '~' and "!~" operators, and in those four built-in
       functions, ERE matching shall be based on text strings; that is, any character  (including
       <newline>  and  the  record  separator) can be embedded in the pattern, and an appropriate
       pattern shall match any character. However, in all awk ERE matching, the  use  of  one  or
       more  NUL  characters  in  the  pattern,  input  record, or text string produces undefined
       results.

   Patterns
       A pattern is any valid expression, a range specified by two  expressions  separated  by  a
       comma, or one of the two special patterns BEGIN or END.

   Special Patterns
       The  awk  utility shall recognize two special patterns, BEGIN and END.  Each BEGIN pattern
       shall be matched once and its associated action executed before the first record of  input
       is  read—except  possibly  by  use  of  the getline function (see Input/Output and General
       Functions) in a prior BEGIN action—and before command line assignment is  done.  Each  END
       pattern  shall be matched once and its associated action executed after the last record of
       input has been read. These two patterns shall have associated actions.

       BEGIN and END shall not combine with other patterns. Multiple BEGIN and END patterns shall
       be  allowed. The actions associated with the BEGIN patterns shall be executed in the order
       specified in the program, as are the END actions. An  END  pattern  can  precede  a  BEGIN
       pattern in a program.

       If  an  awk  program consists of only actions with the pattern BEGIN, and the BEGIN action
       contains no getline function, awk shall exit without  reading  its  input  when  the  last
       statement in the last BEGIN action is executed. If an awk program consists of only actions
       with the pattern END or only actions with the patterns BEGIN and END, the input  shall  be
       read before the statements in the END actions are executed.

   Expression Patterns
       An expression pattern shall be evaluated as if it were an expression in a Boolean context.
       If the result is true, the pattern shall be considered to match, and the associated action
       (if any) shall be executed. If the result is false, the action shall not be executed.

   Pattern Ranges
       A pattern range consists of two expressions separated by a comma; in this case, the action
       shall be performed for all records between  a  match  of  the  first  expression  and  the
       following  match of the second expression, inclusive. At this point, the pattern range can
       be repeated starting at input records subsequent to the end of the matched range.

   Actions
       An action is a sequence of statements as shown in the  grammar  in  Grammar.   Any  single
       statement  can  be  replaced by a statement list enclosed in curly braces. The application
       shall ensure that statements in a statement list are separated by <newline> or <semicolon>
       characters.  Statements  in  a  statement list shall be executed sequentially in the order
       that they appear.

       The expression acting as the conditional in an if statement shall be evaluated and  if  it
       is  non-zero or non-null, the following statement shall be executed; otherwise, if else is
       present, the statement following the else shall be executed.

       The if, while, do...while, for, break, and continue statements  are  based  on  the  ISO C
       standard  (see  Section  1.1.2, Concepts Derived from the ISO C Standard), except that the
       Boolean expressions shall be treated as described in Expressions in awk, and except in the
       case of:

           for (variable in array)

       which  shall  iterate,  assigning each index of array to variable in an unspecified order.
       The results of adding new elements to array within such a for loop  are  undefined.  If  a
       break or continue statement occurs outside of a loop, the behavior is undefined.

       The  delete  statement  shall remove an individual array element. Thus, the following code
       deletes an entire array:

           for (index in array)
               delete array[index]

       The next statement shall cause all further processing of the current input  record  to  be
       abandoned.  The behavior is undefined if a next statement appears or is invoked in a BEGIN
       or END action.

       The exit statement shall invoke all END actions in the order in which they  occur  in  the
       program  source  and  then  terminate  the  program without reading further input. An exit
       statement inside an END action shall terminate the program without  further  execution  of
       END  actions.  If an expression is specified in an exit statement, its numeric value shall
       be the exit status of awk, unless subsequent errors are encountered or a  subsequent  exit
       statement with an expression is executed.

   Output Statements
       Both  print  and  printf  statements shall write to standard output by default. The output
       shall be written to the location specified by output_redirection if one  is  supplied,  as
       follows:

           > expression
           >> expression
           | expression

       In  all  cases,  the  expression  shall be evaluated to produce a string that is used as a
       pathname into which to write (for '>' or ">>") or as a command to be executed  (for  '|').
       Using  the  first  two  forms, if the file of that name is not currently open, it shall be
       opened, creating it if necessary and using the first form, truncating the file. The output
       then  shall be appended to the file. As long as the file remains open, subsequent calls in
       which expression evaluates to the same string value shall  simply  append  output  to  the
       file.  The  file  remains  open  until  the  close  function (see Input/Output and General
       Functions) is called with an expression that evaluates to the same string value.

       The third form shall write output onto a stream piped to  the  input  of  a  command.  The
       stream shall be created if no stream is currently open with the value of expression as its
       command name. The stream created shall be equivalent to one  created  by  a  call  to  the
       popen() function defined in the System Interfaces volume of POSIX.1‐2008 with the value of
       expression as the command argument and a value of w as the mode argument. As long  as  the
       stream  remains  open,  subsequent  calls in which expression evaluates to the same string
       value shall write output to the existing stream. The stream shall remain  open  until  the
       close  function (see Input/Output and General Functions) is called with an expression that
       evaluates to the same string value.  At that time, the stream shall be closed as if  by  a
       call to the pclose() function defined in the System Interfaces volume of POSIX.1‐2008.

       As  described  in  detail  by the grammar in Grammar, these output statements shall take a
       <comma>-separated list of expressions referred to  in  the  grammar  by  the  non-terminal
       symbols expr_list, print_expr_list, or print_expr_list_opt.  This list is referred to here
       as the expression list, and each member is referred to as an expression argument.

       The print statement shall write the value of each expression argument onto  the  indicated
       output  stream  separated  by the current output field separator (see variable OFS above),
       and terminated by the output record separator (see variable  ORS  above).  All  expression
       arguments  shall  be taken as strings, being converted if necessary; this conversion shall
       be as described in Expressions in awk, with the exception that the printf format  in  OFMT
       shall  be  used instead of the value in CONVFMT.  An empty expression list shall stand for
       the whole input record ($0).

       The printf statement shall produce output based on a notation similar to the  File  Format
       Notation  used  to  describe  file  formats  in  this volume of POSIX.1‐2008 (see the Base
       Definitions volume of POSIX.1‐2008, Chapter 5, File Format  Notation).   Output  shall  be
       produced  as  specified  with  the  first  expression  argument  as  the string format and
       subsequent expression arguments as the strings arg1 to argn, inclusive, with the following
       exceptions:

        1. The format shall be an actual character string rather than a graphical representation.
           Therefore, it cannot contain empty character positions.  The  <space>  in  the  format
           string,  in  any  context  other  than  a flag of a conversion specification, shall be
           treated as an ordinary character that is copied to the output.

        2. If the character set contains a '' character and that character appears in the  format
           string, it shall be treated as an ordinary character that is copied to the output.

        3. The  escape  sequences  beginning  with  a  <backslash>  character shall be treated as
           sequences of ordinary characters that are copied to the output. Note that  these  same
           sequences  shall  be interpreted lexically by awk when they appear in literal strings,
           but they shall not be treated specially by the printf statement.

        4. A field width or precision can be specified as the '*' character instead  of  a  digit
           string.  In  this case the next argument from the expression list shall be fetched and
           its numeric value taken as the field width or precision.

        5. The implementation shall not precede or follow output  from  the  d  or  u  conversion
           specifier characters with <blank> characters not specified by the format string.

        6. The  implementation shall not precede output from the o conversion specifier character
           with leading zeros not specified by the format string.

        7. For the c conversion specifier character: if the argument has  a  numeric  value,  the
           character whose encoding is that value shall be output. If the value is zero or is not
           the encoding of any character in the character set, the behavior is undefined. If  the
           argument  does not have a numeric value, the first character of the string value shall
           be output; if the string does not contain any characters, the behavior is undefined.

        8. For each conversion specification that  consumes  an  argument,  the  next  expression
           argument  shall  be  evaluated.  With  the  exception  of  the  c conversion specifier
           character, the  value  shall  be  converted  (according  to  the  rules  specified  in
           Expressions in awk) to the appropriate type for the conversion specification.

        9. If  there  are  insufficient  expression  arguments  to  satisfy  all  the  conversion
           specifications in the format string, the behavior is undefined.

       10. If any character sequence in the format string begins with a '%' character,  but  does
           not form a valid conversion specification, the behavior is unspecified.

       Both print and printf can output at least {LINE_MAX} bytes.

   Functions
       The  awk  language  has a variety of built-in functions: arithmetic, string, input/output,
       and general.

   Arithmetic Functions
       The arithmetic functions, except for int, shall  be  based  on  the  ISO C  standard  (see
       Section  1.1.2,  Concepts  Derived from the ISO C Standard).  The behavior is undefined in
       cases where the ISO C standard specifies that an error be returned or that the behavior is
       undefined. Although the grammar (see Grammar) permits built-in functions to appear with no
       arguments or parentheses, unless the argument or parentheses are indicated as optional  in
       the following list (by displaying them within the "[]" brackets), such use is undefined.

       atan2(y,x)
                 Return arctangent of y/x in radians in the range [−π,π].

       cos(x)    Return cosine of x, where x is in radians.

       sin(x)    Return sine of x, where x is in radians.

       exp(x)    Return the exponential function of x.

       log(x)    Return the natural logarithm of x.

       sqrt(x)   Return the square root of x.

       int(x)    Return  the  argument truncated to an integer. Truncation shall be toward 0 when
                 x>0.

       rand()    Return a random number n, such that 0≤n<1.

       srand([expr])
                 Set the seed value for rand to expr or use the time of day if expr  is  omitted.
                 The previous seed value shall be returned.

   String Functions
       The  string functions in the following list shall be supported.  Although the grammar (see
       Grammar) permits built-in functions to appear with no arguments or parentheses, unless the
       argument  or  parentheses  are  indicated as optional in the following list (by displaying
       them within the "[]" brackets), such use is undefined.

       gsub(ere, repl[, in])
                 Behave like sub (see below), except that it shall replace all occurrences of the
                 regular  expression  (like  the ed utility global substitute) in $0 or in the in
                 argument, when specified.

       index(s, t)
                 Return the position, in characters, numbering from 1, in string s where string t
                 first occurs, or zero if it does not occur at all.

       length[([s])]
                 Return  the  length, in characters, of its argument taken as a string, or of the
                 whole record, $0, if there is no argument.

       match(s, ere)
                 Return the position, in characters, numbering from 1,  in  string  s  where  the
                 extended  regular  expression  ere  occurs, or zero if it does not occur at all.
                 RSTART shall be set to the starting position (which is the same as the  returned
                 value),  zero  if  no  match is found; RLENGTH shall be set to the length of the
                 matched string, −1 if no match is found.

       split(s, a[, fs ])
                 Split the string s into array elements a[1], a[2], ..., a[n], and return n.  All
                 elements  of  the  array  shall  be  deleted  before the split is performed. The
                 separation shall be done with the ERE fs or with the field separator FS if fs is
                 not  given.  Each  array  element shall have a string value when created and, if
                 appropriate, the array  element  shall  be  considered  a  numeric  string  (see
                 Expressions  in  awk).   The  effect  of  a  null  string  as the value of fs is
                 unspecified.

       sprintf(fmt, expr, expr, ...)
                 Format the expressions according to the printf format given by  fmt  and  return
                 the resulting string.

       sub(ere, repl[, in ])
                 Substitute  the  string  repl  in  place  of  the first instance of the extended
                 regular expression ERE in string in and return the number of  substitutions.  An
                 <ampersand>  ('&')  appearing in the string repl shall be replaced by the string
                 from in that matches the ERE. An <ampersand> preceded with a  <backslash>  shall
                 be  interpreted  as  the  literal  <ampersand>  character.  An occurrence of two
                 consecutive <backslash> characters shall be interpreted as just a single literal
                 <backslash>  character.  Any  other  occurrence  of  a <backslash> (for example,
                 preceding any other  character)  shall  be  treated  as  a  literal  <backslash>
                 character.  Note that if repl is a string literal (the lexical token STRING; see
                 Grammar), the handling of the <ampersand> character  occurs  after  any  lexical
                 processing,  including any lexical <backslash>-escape sequence processing. If in
                 is specified and it is not an lvalue (see Expressions in awk), the  behavior  is
                 undefined. If in is omitted, awk shall use the current record ($0) in its place.

       substr(s, m[, n ])
                 Return  the  at  most  n-character  substring  of  s  that begins at position m,
                 numbering from 1. If n is omitted, or if n specifies more  characters  than  are
                 left  in  the string, the length of the substring shall be limited by the length
                 of the string s.

       tolower(s)
                 Return a string based on the string s.  Each character in s that is an uppercase
                 letter  specified  to  have  a  tolower  mapping by the LC_CTYPE category of the
                 current locale shall be replaced in the returned string by the lowercase  letter
                 specified  by  the  mapping.  Other  characters  in  s shall be unchanged in the
                 returned string.

       toupper(s)
                 Return a string based on the string s.  Each character in s that is a  lowercase
                 letter  specified  to  have  a  toupper  mapping by the LC_CTYPE category of the
                 current locale is replaced in  the  returned  string  by  the  uppercase  letter
                 specified  by  the  mapping. Other characters in s are unchanged in the returned
                 string.

       All of the preceding functions that take ERE as a parameter expect a pattern or  a  string
       valued expression that is a regular expression as defined in Regular Expressions.

   Input/Output and General Functions
       The input/output and general functions are:

       close(expression)
                 Close  the  file  or  pipe  opened  by  a print or printf statement or a call to
                 getline with the same string-valued expression.  The limit on the number of open
                 expression arguments is implementation-defined. If the close was successful, the
                 function shall return zero; otherwise, it shall return non-zero.

       expression | getline [var]
                 Read a record of input from a stream piped from the output  of  a  command.  The
                 stream  shall  be  created  if  no  stream  is  currently open with the value of
                 expression as its command name. The stream created shall be  equivalent  to  one
                 created  by  a  call to the popen() function with the value of expression as the
                 command argument and a value of r as the mode argument. As long  as  the  stream
                 remains  open, subsequent calls in which expression evaluates to the same string
                 value shall read subsequent records from the stream.  The  stream  shall  remain
                 open until the close function is called with an expression that evaluates to the
                 same string value. At that time, the stream shall be closed as if by a  call  to
                 the pclose() function. If var is omitted, $0 and NF shall be set; otherwise, var
                 shall be set and, if appropriate, it shall be considered a numeric  string  (see
                 Expressions in awk).

                 The   getline   operator   can   form   ambiguous   constructs  when  there  are
                 unparenthesized operators (including concatenate) to the left of the '|' (to the
                 beginning  of  the  expression  containing  getline).  In the context of the '$'
                 operator, '|' shall behave as if it had a lower precedence than '$'.  The result
                 of  evaluating other operators is unspecified, and conforming applications shall
                 parenthesize properly all such usages.

       getline   Set $0 to the next input record from  the  current  input  file.  This  form  of
                 getline shall set the NF, NR, and FNR variables.

       getline var
                 Set  variable  var  to the next input record from the current input file and, if
                 appropriate, var shall be considered a numeric string (see Expressions in  awk).
                 This form of getline shall set the FNR and NR variables.

       getline [var] < expression
                 Read  the  next  record  of  input  from  a  named file. The expression shall be
                 evaluated to produce a string that is used as a pathname.  If the file  of  that
                 name  is  not  currently open, it shall be opened. As long as the stream remains
                 open, subsequent calls in which expression evaluates to the  same  string  value
                 shall  read  subsequent  records from the file. The file shall remain open until
                 the close function is called with an  expression  that  evaluates  to  the  same
                 string value. If var is omitted, $0 and NF shall be set; otherwise, var shall be
                 set  and,  if  appropriate,  it  shall  be  considered  a  numeric  string  (see
                 Expressions in awk).

                 The   getline   operator   can   form   ambiguous   constructs  when  there  are
                 unparenthesized binary operators (including concatenate) to the right of the '<'
                 (up  to  the  end  of  the  expression  containing  the getline).  The result of
                 evaluating such a construct is unspecified, and  conforming  applications  shall
                 parenthesize properly all such usages.

       system(expression)
                 Execute  the  command given by expression in a manner equivalent to the system()
                 function defined in the System Interfaces volume of POSIX.1‐2008 and return  the
                 exit status of the command.

       All forms of getline shall return 1 for successful input, zero for end-of-file, and −1 for
       an error.

       Where strings are used as the name of a file or pipeline,  the  application  shall  ensure
       that  the  strings  are textually identical. The terminology ``same string value'' implies
       that ``equivalent strings'', even those that differ only by <space> characters,  represent
       different files.

   User-Defined Functions
       The awk language also provides user-defined functions. Such functions can be defined as:

           function name([parameter, ...]) { statements }

       A  function  can  be  referred  to  anywhere in an awk program; in particular, its use can
       precede its definition. The scope of a function is global.

       Function parameters, if present,  can  be  either  scalars  or  arrays;  the  behavior  is
       undefined if an array name is passed as a parameter that the function uses as a scalar, or
       if a scalar expression is passed as a parameter  that  the  function  uses  as  an  array.
       Function parameters shall be passed by value if scalar and by reference if array name.

       The  number  of  parameters  in  the  function  definition  need  not  match the number of
       parameters in the function call. Excess formal parameters can be used as local  variables.
       If  fewer  arguments  are supplied in a function call than are in the function definition,
       the extra parameters that are used in the function body as scalars shall evaluate  to  the
       uninitialized  value  until  they are otherwise initialized, and the extra parameters that
       are used in the function body as arrays shall be treated  as  uninitialized  arrays  where
       each element evaluates to the uninitialized value until otherwise initialized.

       When  invoking  a function, no white space can be placed between the function name and the
       opening parenthesis. Function calls can be nested and recursive calls  can  be  made  upon
       functions.  Upon  return  from any nested or recursive function call, the values of all of
       the calling function's parameters shall be unchanged, except for array  parameters  passed
       by  reference.  The  return statement can be used to return a value. If a return statement
       appears outside of a function definition, the behavior is undefined.

       In the function definition, <newline> characters shall  be  optional  before  the  opening
       brace and after the closing brace. Function definitions can appear anywhere in the program
       where a pattern-action pair is allowed.

   Grammar
       The grammar in this section and the lexical conventions in  the  following  section  shall
       together  describe  the syntax for awk programs. The general conventions for this style of
       grammar are described in Section  1.3,  Grammar  Conventions.   A  valid  program  can  be
       represented  as  the  non-terminal symbol program in the grammar. This formal syntax shall
       take precedence over the preceding text syntax description.

           %token NAME NUMBER STRING ERE
           %token FUNC_NAME   /* Name followed by '(' without white space. */

           /* Keywords */
           %token       Begin   End
           /*          'BEGIN' 'END'                            */

           %token       Break   Continue   Delete   Do   Else
           /*          'break' 'continue' 'delete' 'do' 'else'  */

           %token       Exit   For   Function   If   In
           /*          'exit' 'for' 'function' 'if' 'in'        */

           %token       Next   Print   Printf   Return   While
           /*          'next' 'print' 'printf' 'return' 'while' */

           /* Reserved function names */
           %token BUILTIN_FUNC_NAME
                       /* One token for the following:
                        * atan2 cos sin exp log sqrt int rand srand
                        * gsub index length match split sprintf sub
                        * substr tolower toupper close system
                        */
           %token GETLINE
                       /* Syntactically different from other built-ins. */

           /* Two-character tokens. */
           %token ADD_ASSIGN SUB_ASSIGN MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN POW_ASSIGN
           /*     '+='       '−='       '*='       '/='       '%='       '^=' */

           %token OR   AND  NO_MATCH   EQ   LE   GE   NE   INCR  DECR  APPEND
           /*     '||' '&&' '!~' '==' '<=' '>=' '!=' '++'  '−−'  '>>'   */

           /* One-character tokens. */
           %token '{' '}' '(' ')' '[' ']' ',' ';' NEWLINE
           %token '+' '−' '*' '%' '^' '!' '>' '<' '|' '?' ':' ' " " ' '$' '='

           %start program
           %%

           program          : item_list
                            | actionless_item_list
                            ;

           item_list        : newline_opt
                            | actionless_item_list item terminator
                            | item_list            item terminator
                            | item_list          action terminator
                            ;

           actionless_item_list : item_list            pattern terminator
                            | actionless_item_list pattern terminator
                            ;

           item             : pattern action
                            | Function NAME      '(' param_list_opt ')'
                                  newline_opt action
                            | Function FUNC_NAME '(' param_list_opt ')'
                                  newline_opt action
                            ;

           param_list_opt   : /* empty */
                            | param_list
                            ;

           param_list       : NAME
                            | param_list ',' NAME
                            ;

           pattern          : Begin
                            | End
                            | expr
                            | expr ',' newline_opt expr
                            ;

           action           : '{' newline_opt                             '}'
                            | '{' newline_opt terminated_statement_list   '}'
                            | '{' newline_opt unterminated_statement_list '}'
                            ;

           terminator       : terminator ';'
                            | terminator NEWLINE
                            |            ';'
                            |            NEWLINE
                            ;

           terminated_statement_list : terminated_statement
                            | terminated_statement_list terminated_statement
                            ;

           unterminated_statement_list : unterminated_statement
                            | terminated_statement_list unterminated_statement
                            ;

           terminated_statement : action newline_opt
                            | If '(' expr ')' newline_opt terminated_statement
                            | If '(' expr ')' newline_opt terminated_statement
                                  Else newline_opt terminated_statement
                            | While '(' expr ')' newline_opt terminated_statement
                            | For '(' simple_statement_opt ';'
                                 expr_opt ';' simple_statement_opt ')' newline_opt
                                 terminated_statement
                            | For '(' NAME In NAME ')' newline_opt
                                 terminated_statement
                            | ';' newline_opt
                            | terminatable_statement NEWLINE newline_opt
                            | terminatable_statement ';'     newline_opt
                            ;

           unterminated_statement : terminatable_statement
                            | If '(' expr ')' newline_opt unterminated_statement
                            | If '(' expr ')' newline_opt terminated_statement
                                 Else newline_opt unterminated_statement
                            | While '(' expr ')' newline_opt unterminated_statement
                            | For '(' simple_statement_opt ';'
                             expr_opt ';' simple_statement_opt ')' newline_opt
                                 unterminated_statement
                            | For '(' NAME In NAME ')' newline_opt
                                 unterminated_statement
                            ;

           terminatable_statement : simple_statement
                            | Break
                            | Continue
                            | Next
                            | Exit expr_opt
                            | Return expr_opt
                            | Do newline_opt terminated_statement While '(' expr ')'
                            ;

           simple_statement_opt : /* empty */
                            | simple_statement
                            ;

           simple_statement : Delete NAME '[' expr_list ']'
                            | expr
                            | print_statement
                            ;

           print_statement  : simple_print_statement
                            | simple_print_statement output_redirection
                            ;

           simple_print_statement : Print  print_expr_list_opt
                            | Print  '(' multiple_expr_list ')'
                            | Printf print_expr_list
                            | Printf '(' multiple_expr_list ')'
                            ;

           output_redirection : '>'    expr
                            | APPEND expr
                            | '|'    expr
                            ;

           expr_list_opt    : /* empty */
                            | expr_list
                            ;

           expr_list        : expr
                            | multiple_expr_list
                            ;

           multiple_expr_list : expr ',' newline_opt expr
                            | multiple_expr_list ',' newline_opt expr
                            ;

           expr_opt         : /* empty */
                            | expr
                            ;

           expr             : unary_expr
                            | non_unary_expr
                            ;

           unary_expr       : '+' expr
                            | '−' expr
                            | unary_expr '^'      expr
                            | unary_expr '*'      expr
                            | unary_expr '/'      expr
                            | unary_expr '%'      expr
                            | unary_expr '+'      expr
                            | unary_expr '−'      expr
                            | unary_expr          non_unary_expr
                            | unary_expr '<'      expr
                            | unary_expr LE       expr
                            | unary_expr NE       expr
                            | unary_expr EQ       expr
                            | unary_expr '>'      expr
                            | unary_expr GE       expr
                            | unary_expr '~'      expr
                            | unary_expr NO_MATCH expr
                            | unary_expr In NAME
                            | unary_expr AND newline_opt expr
                            | unary_expr OR  newline_opt expr
                            | unary_expr '?' expr ':' expr
                            | unary_input_function
                            ;

           non_unary_expr   : '(' expr ')'
                            | '!' expr
                            | non_unary_expr '^'      expr
                            | non_unary_expr '*'      expr
                            | non_unary_expr '/'      expr
                            | non_unary_expr '%'      expr
                            | non_unary_expr '+'      expr
                            | non_unary_expr '−'      expr
                            | non_unary_expr          non_unary_expr
                            | non_unary_expr '<'      expr
                            | non_unary_expr LE       expr
                            | non_unary_expr NE       expr
                            | non_unary_expr EQ       expr
                            | non_unary_expr '>'      expr
                            | non_unary_expr GE       expr
                            | non_unary_expr '~'      expr
                            | non_unary_expr NO_MATCH expr
                            | non_unary_expr In NAME
                            | '(' multiple_expr_list ')' In NAME
                            | non_unary_expr AND newline_opt expr
                            | non_unary_expr OR  newline_opt expr
                            | non_unary_expr '?' expr ':' expr
                            | NUMBER
                            | STRING
                            | lvalue
                            | ERE
                            | lvalue INCR
                            | lvalue DECR
                            | INCR lvalue
                            | DECR lvalue
                            | lvalue POW_ASSIGN expr
                            | lvalue MOD_ASSIGN expr
                            | lvalue MUL_ASSIGN expr
                            | lvalue DIV_ASSIGN expr
                            | lvalue ADD_ASSIGN expr
                            | lvalue SUB_ASSIGN expr
                            | lvalue '=' expr
                            | FUNC_NAME '(' expr_list_opt ')'
                                 /* no white space allowed before '(' */
                            | BUILTIN_FUNC_NAME '(' expr_list_opt ')'
                            | BUILTIN_FUNC_NAME
                            | non_unary_input_function
                            ;

           print_expr_list_opt : /* empty */
                            | print_expr_list
                            ;

           print_expr_list  : print_expr
                            | print_expr_list ',' newline_opt print_expr
                            ;

           print_expr       : unary_print_expr
                            | non_unary_print_expr
                            ;

           unary_print_expr : '+' print_expr
                            | '−' print_expr
                            | unary_print_expr '^'      print_expr
                            | unary_print_expr '*'      print_expr
                            | unary_print_expr '/'      print_expr
                            | unary_print_expr '%'      print_expr
                            | unary_print_expr '+'      print_expr
                            | unary_print_expr '−'      print_expr
                            | unary_print_expr          non_unary_print_expr
                            | unary_print_expr '~'      print_expr
                            | unary_print_expr NO_MATCH print_expr
                            | unary_print_expr In NAME
                            | unary_print_expr AND newline_opt print_expr
                            | unary_print_expr OR  newline_opt print_expr
                            | unary_print_expr '?' print_expr ':' print_expr
                            ;

           non_unary_print_expr : '(' expr ')'
                            | '!' print_expr
                            | non_unary_print_expr '^'      print_expr
                            | non_unary_print_expr '*'      print_expr
                            | non_unary_print_expr '/'      print_expr
                            | non_unary_print_expr '%'      print_expr
                            | non_unary_print_expr '+'      print_expr
                            | non_unary_print_expr '−'      print_expr
                            | non_unary_print_expr          non_unary_print_expr
                            | non_unary_print_expr '~'      print_expr
                            | non_unary_print_expr NO_MATCH print_expr
                            | non_unary_print_expr In NAME
                            | '(' multiple_expr_list ')' In NAME
                            | non_unary_print_expr AND newline_opt print_expr
                            | non_unary_print_expr OR  newline_opt print_expr
                            | non_unary_print_expr '?' print_expr ':' print_expr
                            | NUMBER
                            | STRING
                            | lvalue
                            | ERE
                            | lvalue INCR
                            | lvalue DECR
                            | INCR lvalue
                            | DECR lvalue
                            | lvalue POW_ASSIGN print_expr
                            | lvalue MOD_ASSIGN print_expr
                            | lvalue MUL_ASSIGN print_expr
                            | lvalue DIV_ASSIGN print_expr
                            | lvalue ADD_ASSIGN print_expr
                            | lvalue SUB_ASSIGN print_expr
                            | lvalue '=' print_expr
                            | FUNC_NAME '(' expr_list_opt ')'
                                /* no white space allowed before '(' */
                            | BUILTIN_FUNC_NAME '(' expr_list_opt ')'
                            | BUILTIN_FUNC_NAME
                            ;

           lvalue           : NAME
                            | NAME '[' expr_list ']'
                            | '$' expr
                            ;

           non_unary_input_function : simple_get
                            | simple_get '<' expr
                            | non_unary_expr '|' simple_get
                            ;

           unary_input_function : unary_expr '|' simple_get
                            ;

           simple_get       : GETLINE
                            | GETLINE lvalue
                            ;

           newline_opt      : /* empty */
                            | newline_opt NEWLINE
                            ;

       This grammar has several ambiguities that shall be resolved as follows:

        *  Operator precedence and associativity shall be as described in Table 4-1,  Expressions
           in Decreasing Precedence in awk.

        *  In  case of ambiguity, an else shall be associated with the most immediately preceding
           if that would satisfy the grammar.

        *  In some contexts, a <slash> ('/') that is used to surround an ERE could  also  be  the
           division  operator.   This  shall be resolved in such a way that wherever the division
           operator could appear, a <slash> is assumed to be the division operator. (There is  no
           unary division operator.)

       Each expression in an awk program shall conform to the precedence and associativity rules,
       even when this is not needed to resolve an ambiguity. For example, because '$' has  higher
       precedence than '++', the string "$x++−−" is not a valid awk expression, even though it is
       unambiguously parsed by the grammar as "$(x++)−−".

       One convention that might not be obvious  from  the  formal  grammar  is  where  <newline>
       characters  are  acceptable.  There  are  several obvious placements such as terminating a
       statement, and a <backslash> can be  used  to  escape  <newline>  characters  between  any
       lexical  tokens.  In  addition,  <newline>  characters  without <backslash> characters can
       follow a comma, an open brace, logical AND operator ("&&"), logical  OR  operator  ("||"),
       the  do  keyword,  the  else  keyword, and the closing parenthesis of an if, for, or while
       statement. For example:

           { print  $1,
                    $2 }

   Lexical Conventions
       The lexical conventions for awk programs, with respect to the preceding grammar, shall  be
       as follows:

        1. Except as noted, awk shall recognize the longest possible token or delimiter beginning
           at a given point.

        2. A comment shall consist of any characters beginning with the  <number-sign>  character
           and  terminated by, but excluding the next occurrence of, a <newline>.  Comments shall
           have no effect, except to delimit lexical tokens.

        3. The <newline> shall be recognized as the token NEWLINE.

        4. A <backslash> character immediately followed by a <newline> shall have no effect.

        5. The token STRING shall represent a string constant. A string constant shall begin with
           the  character  '"'.   Within  a  string  constant,  a  <backslash> character shall be
           considered to begin an  escape  sequence  as  specified  in  the  table  in  the  Base
           Definitions volume of POSIX.1‐2008, Chapter 5, File Format Notation ('\\', '\a', '\b',
           '\f', '\n', '\r', '\t', '\v').  In addition, the escape sequences in Table 4-2, Escape
           Sequences  in  awk  shall  be  recognized. A <newline> shall not occur within a string
           constant. A string constant shall be terminated by the first unescaped  occurrence  of
           the  character  '"'  after  the  one that begins the string constant. The value of the
           string shall be the  sequence  of  all  unescaped  characters  and  values  of  escape
           sequences between, but not including, the two delimiting '"' characters.

        6. The  token  ERE  represents  an  extended regular expression constant. An ERE constant
           shall begin with  the  <slash>  character.  Within  an  ERE  constant,  a  <backslash>
           character shall be considered to begin an escape sequence as specified in the table in
           the Base Definitions volume of POSIX.1‐2008, Chapter  5,  File  Format  Notation.   In
           addition,  the  escape  sequences  in  Table  4-2,  Escape  Sequences  in awk shall be
           recognized. The application shall ensure that a <newline> does not occur within an ERE
           constant. An ERE constant shall be terminated by the first unescaped occurrence of the
           <slash> character after the one that begins the ERE  constant.  The  extended  regular
           expression  represented  by  the  ERE  constant shall be the sequence of all unescaped
           characters and values  of  escape  sequences  between,  but  not  including,  the  two
           delimiting <slash> characters.

        7. A  <blank>  shall have no effect, except to delimit lexical tokens or within STRING or
           ERE tokens.

        8. The token NUMBER shall represent a numeric constant. Its form and numeric value  shall
           either  be equivalent to the decimal-floating-constant token as specified by the ISO C
           standard, or it shall be a sequence of decimal digits and shall  be  evaluated  as  an
           integer constant in decimal. In addition, implementations may accept numeric constants
           with  the  form  and  numeric  value  equivalent  to  the   hexadecimal-constant   and
           hexadecimal-floating-constant tokens as specified by the ISO C standard.

           If  the  value  is  too  large  or  too  small to be representable (see Section 1.1.2,
           Concepts Derived from the ISO C Standard), the behavior is undefined.

        9. A sequence of underscores, digits, and alphabetics from  the  portable  character  set
           (see  the  Base  Definitions  volume  of POSIX.1‐2008, Section 6.1, Portable Character
           Set), beginning with an <underscore> or alphabetic character, shall  be  considered  a
           word.

       10. The  following  words  are keywords that shall be recognized as individual tokens; the
           name of the token is the same as the keyword:

           BEGIN      delete     END        function   in         printf
           break      do         exit       getline    next       return
           continue   else       for        if         print      while

       11. The following words are names of built-in functions and shall  be  recognized  as  the
           token BUILTIN_FUNC_NAME:

           atan2     gsub      log       split     sub       toupper
           close     index     match     sprintf   substr
           cos       int       rand      sqrt      system
           exp       length    sin       srand     tolower

           The  above-listed  keywords  and  names  of built-in functions are considered reserved
           words.

       12. The token NAME shall consist of a word that is not a keyword or a name of  a  built-in
           function  and  is  not  followed  immediately  (without  any  delimiters)  by  the '('
           character.

       13. The token FUNC_NAME shall consist of a word that is not a  keyword  or  a  name  of  a
           built-in function, followed immediately (without any delimiters) by the '(' character.
           The '(' character shall not be included as part of the token.

       14. The following two-character sequences shall be recognized as the named tokens:

                              ┌───────────┬──────────┬────────────┬──────────┐
                              │Token NameSequenceToken NameSequence │
                              ├───────────┼──────────┼────────────┼──────────┤
                              │ADD_ASSIGN │    +=    │ NO_MATCH   │    !~    │
                              │SUB_ASSIGN │    −=    │ EQ         │    ==    │
                              │MUL_ASSIGN │    *=    │ LE         │    <=    │
                              │DIV_ASSIGN │    /=    │ GE         │    >=    │
                              │MOD_ASSIGN │    %=    │ NE         │    !=    │
                              │POW_ASSIGN │    ^=    │ INCR       │    ++    │
                              │OR         │    ||    │ DECR       │    −−    │
                              │AND        │    &&    │ APPEND     │    >>    │
                              └───────────┴──────────┴────────────┴──────────┘
       15. The following single characters shall be recognized as  tokens  whose  names  are  the
           character:

               <newline> { } ( ) [ ] , ; +  * % ^ ! > < | ? :  " "  $ =

       There  is  a  lexical  ambiguity  between the token ERE and the tokens '/' and DIV_ASSIGN.
       When an input sequence begins with a <slash> character in any syntactic context where  the
       token  '/'  or DIV_ASSIGN could appear as the next token in a valid program, the longer of
       those two tokens that can be recognized  shall  be  recognized.  In  any  other  syntactic
       context  where  the token ERE could appear as the next token in a valid program, the token
       ERE shall be recognized.

EXIT STATUS

       The following exit values shall be returned:

        0    All input files were processed successfully.

       >0    An error occurred.

       The exit status can be altered within the program by using an exit expression.

CONSEQUENCES OF ERRORS

       If any file operand is specified and the named file cannot be accessed, awk shall write  a
       diagnostic message to standard error and terminate without any further action.

       If  the  program  specified  by  either the program operand or a progfile operand is not a
       valid awk program (as specified in the EXTENDED  DESCRIPTION  section),  the  behavior  is
       undefined.

       The following sections are informative.

APPLICATION USAGE

       The  index,  length,  match,  and  substr  functions  should  not be confused with similar
       functions in the ISO C standard; the awk versions deal with characters,  while  the  ISO C
       standard deals with bytes.

       Because  the concatenation operation is represented by adjacent expressions rather than an
       explicit operator, it is  often  necessary  to  use  parentheses  to  enforce  the  proper
       evaluation precedence.

EXAMPLES

       The  awk  program  specified  in  the command line is most easily specified within single-
       quotes (for example, 'program') for applications using sh, because awk  programs  commonly
       contain  characters  that  are special to the shell, including double-quotes. In the cases
       where an awk program contains single-quote characters, it is usually  easiest  to  specify
       most  of the program as strings within single-quotes concatenated by the shell with quoted
       single-quote characters. For example:

           awk '/'\''/ { print "quote:", $0 }'

       prints all lines from the standard input containing  a  single-quote  character,  prefixed
       with quote:.

       The following are examples of simple awk programs:

        1. Write to the standard output all input lines for which field 3 is greater than 5:

               $3 > 5

        2. Write every tenth line:

               (NR % 10) == 0

        3. Write any line with a substring matching the regular expression:

               /(G|D)(2[0−9][[:alpha:]]*)/

        4. Print  any  line  with  a substring containing a 'G' or 'D', followed by a sequence of
           digits and characters. This example uses character classes digit and  alpha  to  match
           language-independent digit and alphabetic characters respectively:

               /(G|D)([[:digit:][:alpha:]]*)/

        5. Write any line in which the second field matches the regular expression and the fourth
           field does not:

               $2  " "  /xyz/ && $4 ! " "  /xyz/

        6. Write any line in which the second field contains a <backslash>:

               $2  " "  /\\/

        7. Write any  line  in  which  the  second  field  contains  a  <backslash>.   Note  that
           <backslash>-escapes  are  interpreted  twice; once in lexical processing of the string
           and once in processing the regular expression:

               $2  " "  "\\\\"

        8. Write the second to the last and the last field in each line. Separate the fields by a
           <colon>:

               {OFS=":";print $(NF−1), $NF}

        9. Write  the  line  number  and  number  of  fields  in  each  line.  The  three strings
           representing the line number, the <colon>, and the number of fields  are  concatenated
           and that string is written to standard output:

               {print NR ":" NF}

       10. Write lines longer than 72 characters:

               length($0) > 72

       11. Write the first two fields in opposite order separated by OFS:

               { print $2, $1 }

       12. Same,  with  input  fields  separated by a <comma> or <space> and <tab> characters, or
           both:

               BEGIN { FS = ",[ \t]*|[ \t]+" }
                     { print $2, $1 }

       13. Add up the first column, print sum, and average:

                     {s += $1 }
               END   {print "sum is ", s, " average is", s/NR}

       14. Write fields in reverse order, one per line (many lines out for each line in):

               { for (i = NF; i > 0; −−i) print $i }

       15. Write all lines between occurrences of the strings start and stop:

               /start/, /stop/

       16. Write all lines whose first field is different from the previous one:

               $1 != prev { print; prev = $1 }

       17. Simulate echo:

               BEGIN  {
                       for (i = 1; i < ARGC; ++i)
                       printf("%s%s", ARGV[i], i==ARGC−1?"\n":" ")
               }

       18. Write the path prefixes contained in the PATH environment variable, one per line:

               BEGIN  {
                       n = split (ENVIRON["PATH"], path, ":")
                       for (i = 1; i <= n; ++i)
                       print path[i]
               }

       19. If there is a file named input containing page headers of the form: Page #

           and a file named program that contains:

               /Page/   { $2 = n++; }
                        { print }

           then the command line:

               awk −f program n=5 input

           prints the file input, filling in page numbers starting at 5.

RATIONALE

       This description is  based  on  the  new  awk,  ``nawk'',  (see  the  referenced  The  AWK
       Programming Language), which introduced a number of new features to the historical awk:

        1. New keywords: delete, do, function, return

        2. New built-in functions: atan2, close, cos, gsub, match, rand, sin, srand, sub, system

        3. New predefined variables: FNR, ARGC, ARGV, RSTART, RLENGTH, SUBSEP

        4. New expression operators: ?, :, ,, ^

        5. The  FS  variable  and  the  third  argument to split, now treated as extended regular
           expressions.

        6. The operator precedence, changed to more closely match the C language.   Two  examples
           of code that operate differently are:

               while ( n /= 10 > 1) ...
               if (!"wk" ~ /bwk/) ...

       Several features have been added based on newer implementations of awk:

        *  Multiple instances of −f progfile are permitted.

        *  The new option −v assignment.

        *  The new predefined variable ENVIRON.

        *  New built-in functions toupper and tolower.

        *  More formatting capabilities are added to printf to match the ISO C standard.

       The  overall  awk syntax has always been based on the C language, with a few features from
       the shell command language and other sources.  Because  of  this,  it  is  not  completely
       compatible  with  any other language, which has caused confusion for some users. It is not
       the intent of the standard developers to address  such  issues.  A  few  relatively  minor
       changes toward making the language more compatible with the ISO C standard were made; most
       of these changes are based on similar changes  in  recent  implementations,  as  described
       above.  There  remain  several  C-language  conventions  that  are not in awk.  One of the
       notable ones is  the  <comma>  operator,  which  is  commonly  used  to  specify  multiple
       expressions  in  the C language for statement. Also, there are various places where awk is
       more restrictive than the C language regarding the type of expression that can be used  in
       a given context. These limitations are due to the different features that the awk language
       does provide.

       Regular expressions in awk have been extended somewhat from historical implementations  to
       make them a pure superset of extended regular expressions, as defined by POSIX.1‐2008 (see
       the Base Definitions volume of POSIX.1‐2008, Section 9.4, Extended  Regular  Expressions).
       The main extensions are internationalization features and interval expressions. Historical
       implementations of awk have long supported <backslash>-escape sequences as an extension to
       extended  regular  expressions, and this extension has been retained despite inconsistency
       with other utilities. The number of escape sequences recognized in both  extended  regular
       expressions and strings has varied (generally increasing with time) among implementations.
       The set specified by POSIX.1‐2008 includes most sequences known to be supported by popular
       implementations  and  by  the  ISO C  standard.  One  sequence  that  is  not supported is
       hexadecimal value escapes beginning with '\x'.  This would allow values expressed in  more
       than  9  bits to be used within awk as in the ISO C standard. However, because this syntax
       has a non-deterministic length, it does not  permit  the  subsequent  character  to  be  a
       hexadecimal  digit.  This  limitation  can  be  dealt with in the C language by the use of
       lexical string concatenation. In the awk language, concatenation could also be a  solution
       for  strings,  but  not  for  extended  regular  expressions (either lexical ERE tokens or
       strings used dynamically as regular expressions). Because of this limitation, the  feature
       has not been added to POSIX.1‐2008.

       When  a string variable is used in a context where an extended regular expression normally
       appears (where the lexical token ERE is used in the grammar) the string does  not  contain
       the literal <slash> characters.

       Some versions of awk allow the form:

           func name(args, ... ) { statements }

       This  has  been  deprecated  by  the  authors  of  the  language, who asked that it not be
       specified.

       Historical implementations of awk produce an error if a next statement is  executed  in  a
       BEGIN action, and cause awk to terminate if a next statement is executed in an END action.
       This behavior has not been documented, and it was not believed that it  was  necessary  to
       standardize it.

       The  specification  of conversions between string and numeric values is much more detailed
       than in the documentation of historical implementations  or  in  the  referenced  The  AWK
       Programming  Language.  Although  most  of  the  behavior is designed to be intuitive, the
       details are necessary to ensure compatible behavior from different  implementations.  This
       is  especially  important  in  relational  expressions  since  the  types  of the operands
       determine whether a string or numeric comparison is performed. From the perspective of  an
       application  developer, it is usually sufficient to expect intuitive behavior and to force
       conversions (by adding zero or concatenating a null string) when the type of an expression
       does  not  obviously  match  what  is  needed.  The  intent has been to specify historical
       practice in almost all cases. The one exception is that,  in  historical  implementations,
       variables and constants maintain both string and numeric values after their original value
       is converted by any use. This means that referencing  a  variable  or  constant  can  have
       unexpected  side-effects.  For  example,  with  historical  implementations  the following
       program:

           {
               a = "+2"
               b = 2
               if (NR % 2)
                   c = a + b
               if (a == b)
                   print "numeric comparison"
               else
                   print "string comparison"
           }

       would perform a numeric comparison (and output numeric comparison) for  each  odd-numbered
       line,  but  perform  a  string  comparison  (and  output string comparison) for each even-
       numbered line. POSIX.1‐2008 ensures that comparisons will be numeric  if  necessary.  With
       historical implementations, the following program:

           BEGIN {
               OFMT = "%e"
               print 3.14
               OFMT = "%f"
               print 3.14
           }

       would  output  "3.140000e+00"  twice,  because  in the second print statement the constant
       "3.14" would have a string value from the previous conversion. POSIX.1‐2008 requires  that
       the  output  of  the  second  print  statement  be "3.140000".  The behavior of historical
       implementations was seen as too unintuitive and unpredictable.

       It was pointed out that with the rules contained in early  drafts,  the  following  script
       would print nothing:

           BEGIN {
               y[1.5] = 1
               OFMT = "%e"
               print y[1.5]
           }

       Therefore, a new variable, CONVFMT, was introduced. The OFMT variable is now restricted to
       affecting output conversions of numbers to  strings  and  CONVFMT  is  used  for  internal
       conversions,  such as comparisons or array indexing. The default value is the same as that
       for OFMT, so unless a program changes CONVFMT (which no historical program would  do),  it
       will receive the historical behavior associated with internal string conversions.

       The  POSIX awk lexical and syntactic conventions are specified more formally than in other
       sources. Again the intent has been to specify historical practice. One convention that may
       not  be obvious from the formal grammar as in other verbal descriptions is where <newline>
       characters are acceptable. There are several obvious  placements  such  as  terminating  a
       statement,  and  a  <backslash>  can  be  used  to escape <newline> characters between any
       lexical tokens. In addition,  <newline>  characters  without  <backslash>  characters  can
       follow  a  comma,  an  open  brace,  a  logical AND operator ("&&"), a logical OR operator
       ("||"), the do keyword, the else keyword, and the closing parenthesis of an  if,  for,  or
       while statement. For example:

           { print $1,
                   $2 }

       The  requirement  that  awk  add  a  trailing <newline> to the program argument text is to
       simplify the grammar, making it match a text  file  in  form.  There  is  no  way  for  an
       application or test suite to determine whether a literal <newline> is added or whether awk
       simply acts as if it did.

       POSIX.1‐2008 requires several changes from historical implementations in order to  support
       internationalization.  Probably  the  most subtle of these is the use of the decimal-point
       character, defined by the  LC_NUMERIC  category  of  the  locale,  in  representations  of
       floating-point  numbers.   This  locale-specific  character is used in recognizing numeric
       input, in converting between  strings  and  numeric  values,  and  in  formatting  output.
       However,  regardless of locale, the <period> character (the decimal-point character of the
       POSIX locale) is  the  decimal-point  character  recognized  in  processing  awk  programs
       (including assignments in command line arguments). This is essentially the same convention
       as the one used in the ISO C standard. The difference is that the C language includes  the
       setlocale()  function,  which permits an application to modify its locale. Because of this
       capability, a C application begins executing with its locale set to the C locale, and only
       executes  in  the  environment-specified  locale  after  an  explicit call to setlocale().
       However,  adding  such  an  elaborate  new  feature  to  the  awk  language  was  seen  as
       inappropriate for POSIX.1‐2008. It is possible to execute an awk program explicitly in any
       desired locale by setting the environment in the shell.

       The undefined behavior resulting from NULs in extended regular expressions  allows  future
       extensions for the GNU gawk program to process binary data.

       The  behavior  in  the  case  of  invalid  awk programs (including lexical, syntactic, and
       semantic errors) is undefined because it was considered overly limiting on implementations
       to  specify.  In most cases such errors can be expected to produce a diagnostic and a non-
       zero exit status. However, some implementations may choose to extend the language in  ways
       that  make  use  of  certain  invalid constructs. Other invalid constructs might be deemed
       worthy of a warning, but otherwise cause some reasonable behavior. Still other  constructs
       may  be very difficult to detect in some implementations.  Also, different implementations
       might detect a given error during an initial parsing of the program  (before  reading  any
       input  files)  while  others might detect it when executing the program after reading some
       input. Implementors should be aware that  diagnosing  errors  as  early  as  possible  and
       producing  useful  diagnostics  can  ease  debugging  of  applications,  and  thus make an
       implementation more usable.

       The unspecified behavior from using multi-character RS values is to allow possible  future
       extensions  based  on  extended regular expressions used for record separators. Historical
       implementations take the first character of the string and ignore the others.

       Unspecified behavior when split(string,array,<null>) is used is to allow a proposed future
       extension that would split up a string into an array of individual characters.

       In  the  context of the getline function, equally good arguments for different precedences
       of the | and < operators can be made. Historical practice has been that:

           getline < "a" "b"

       is parsed as:

           ( getline < "a" ) "b"

       although many would argue that the intent was that the file ab should be read. However:

           getline < "x" + 1

       parses as:

           getline < ( "x" + 1 )

       Similar problems occur with the | version of getline, particularly in combination with  $.
       For example:

           $"echo hi" | getline

       (This  situation  is  particularly  problematic  when used in a print statement, where the
       |getline part might be a redirection of the print.)

       Since in most cases such constructs are not (or at least should not) be used (because they
       have a natural ambiguity for which there is no conventional parsing), the meaning of these
       constructs has been  made  explicitly  unspecified.  (The  effect  is  that  a  conforming
       application that runs into the problem must parenthesize to resolve the ambiguity.)  There
       appeared to be few if any actual uses of such constructs.

       Grammars can be written that  would  cause  an  error  under  these  circumstances.  Where
       backwards-compatibility  is  not  a large consideration, implementors may wish to use such
       grammars.

       Some historical implementations have allowed some built-in functions to be called  without
       an  argument  list, the result being a default argument list chosen in some ``reasonable''
       way. Use of length as a synonym for length($0) is the only one  of  these  forms  that  is
       thought  to  be widely known or widely used; this particular form is documented in various
       places (for example, most historical awk reference pages, although not in  the  referenced
       The  AWK  Programming  Language)  as  legitimate  practice.   With this exception, default
       argument lists have always been undocumented and vaguely defined, and it  is  not  at  all
       clear how (or if) they should be generalized to user-defined functions. They add no useful
       functionality and preclude possible future extensions that might need  to  name  functions
       without  calling  them.  Not  standardizing  them  seems the simplest course. The standard
       developers considered that length merited special treatment, however, since  it  has  been
       documented  in  the  past  and  sees  possibly  substantial  use  in  historical programs.
       Accordingly, this usage has been made legitimate,  but  Issue 5  removed  the  obsolescent
       marking  for  XSI-conforming  implementations  and  many otherwise conforming applications
       depend on this feature.

       In sub and gsub, if repl is  a  string  literal  (the  lexical  token  STRING),  then  two
       consecutive  <backslash>  characters  should  be  used  in  the  string to ensure a single
       <backslash> will precede the <ampersand> when  the  resultant  string  is  passed  to  the
       function.  (For example, to specify one literal <ampersand> in the replacement string, use
       gsub(ERE, "\\&").)

       Historically, the only special character in the repl  argument  of  sub  and  gsub  string
       functions  was  the  <ampersand>  ('&')  character  and  preceding it with the <backslash>
       character was used to turn off its special meaning.

       The description in  the  ISO POSIX‐2:1993  standard  introduced  behavior  such  that  the
       <backslash>  character  was another special character and it was unspecified whether there
       were any  other  special  characters.  This  description  introduced  several  portability
       problems,  some  of  which  are described below, and so it has been replaced with the more
       historical description. Some of the problems include:

        *  Historically, to create the replacement string, a script could use  gsub(ERE,  "\\&"),
           but  with  the  ISO POSIX‐2:1993  standard  wording, it was necessary to use gsub(ERE,
           "\\\\&").  The <backslash> characters are doubled here because all string literals are
           subject to lexical analysis, which would reduce each pair of <backslash> characters to
           a single <backslash> before being passed to gsub.

        *  Since it was unspecified what the special characters were,  for  portable  scripts  to
           guarantee  that  characters  are  printed literally, each character had to be preceded
           with a <backslash>.  (For example, a portable script had to use gsub(ERE, "\\h\\i") to
           produce a replacement string of "hi".)

       The description for comparisons in the ISO POSIX‐2:1993 standard did not properly describe
       historical practice because of the way  numeric  strings  are  compared  as  numbers.  The
       current rules cause the following code:

           if (0 == "000")
               print "strange, but true"
           else
               print "not true"

       to  do  a  numeric comparison, causing the if to succeed. It should be intuitively obvious
       that this is incorrect behavior, and indeed, no historical implementation of awk  actually
       behaves this way.

       To  fix  this problem, the definition of numeric string was enhanced to include only those
       values obtained from specific circumstances (mostly external  sources)  where  it  is  not
       possible  to  determine  unambiguously  whether  the value is intended to be a string or a
       numeric.

       Variables that are assigned to a numeric string shall also be treated as a numeric string.
       (For  example,  the  notion  of a numeric string can be propagated across assignments.) In
       comparisons, all variables having the uninitialized value are to be treated as  a  numeric
       operand evaluating to the numeric value zero.

       Uninitialized  variables include all types of variables including scalars, array elements,
       and fields. The definition of an uninitialized value in Variables and Special Variables is
       necessary  to  describe the value placed on uninitialized variables and on fields that are
       valid (for example, < $NF) but have no characters  in  them  and  to  describe  how  these
       variables are to be used in comparisons. A valid field, such as $1, that has no characters
       in it can be obtained from an input  line  of  "\t\t"  when  FS='\t'.   Historically,  the
       comparison ($1<10) was done numerically after evaluating $1 to the value zero.

       The  phrase  ``...  also  shall have the numeric value of the numeric string'' was removed
       from several sections of the ISO POSIX‐2:1993 standard because is specifies an unnecessary
       implementation  detail. It is not necessary for POSIX.1‐2008 to specify that these objects
       be assigned two different values.  It is only necessary to specify that these objects  may
       evaluate to two different values depending on context.

       Historical  implementations of awk did not parse hexadecimal integer or floating constants
       like "0xa" and "0xap0".  Due to an oversight, the  2001  through  2004  editions  of  this
       standard  required  support  for  hexadecimal  floating  constants.  This  was  due to the
       reference  to  atof().   This  version  of  the  standard  allows  but  does  not  require
       implementations to use atof() and includes a description of how floating-point numbers are
       recognized as an alternative to match historic behavior. The intent of this change  is  to
       allow  implementations  to  recognize  floating-point  constants  according  to either the
       ISO/IEC 9899:1990 standard or ISO/IEC 9899:1999 standard, and to allow (but  not  require)
       implementations to recognize hexadecimal integer constants.

       Historical  implementations  of  awk did not support floating-point infinities and NaNs in
       numeric strings; e.g., "−INF" and "NaN".  However, implementations that use the atof()  or
       strtod()  functions to do the conversion picked up support for these values if they used a
       ISO/IEC 9899:1999 standard version of the function instead of a ISO/IEC 9899:1990 standard
       version.  Due  to  an  oversight,  the 2001 through 2004 editions of this standard did not
       allow support for infinities and NaNs, but in this revision support is  allowed  (but  not
       required).  This  is  a silent change to the behavior of awk programs; for example, in the
       POSIX locale the expression:

           ("-INF" + 0 < 0)

       formerly had the value 0 because "−INF" converted to 0, but now it may have the value 0 or
       1.

FUTURE DIRECTIONS

       None.

SEE ALSO

       Section 1.3, Grammar Conventions, grep, lex, sed

       The Base Definitions volume of POSIX.1‐2008, Chapter 5, File Format Notation, Section 6.1,
       Portable Character Set, Chapter 8, Environment Variables, Chapter 9, Regular  Expressions,
       Section 12.2, Utility Syntax Guidelines

       The   System   Interfaces  volume  of  POSIX.1‐2008,  atof(),  exec,  isspace(),  popen(),
       setlocale(), strtod()

COPYRIGHT

       Portions of this text are reprinted and  reproduced  in  electronic  form  from  IEEE  Std
       1003.1,  2013  Edition,  Standard  for Information Technology -- Portable Operating System
       Interface (POSIX), The Open Group Base Specifications Issue 7, Copyright (C) 2013  by  the
       Institute  of  Electrical  and  Electronics  Engineers,  Inc and The Open Group.  (This is
       POSIX.1-2008 with the  2013  Technical  Corrigendum  1  applied.)  In  the  event  of  any
       discrepancy  between  this  version and the original IEEE and The Open Group Standard, the
       original IEEE and The Open Group Standard is the referee document. The  original  Standard
       can be obtained online at http://www.unix.org/online.html .

       Any  typographical  or  formatting errors that appear in this page are most likely to have
       been introduced during the conversion of the source files to man page  format.  To  report
       such errors, see https://www.kernel.org/doc/man-pages/reporting_bugs.html .