gawk: Getline/Pipe

1 
1 4.10.5 Using 'getline' from a Pipe
1 ----------------------------------
1 
1      Omniscience has much to recommend it.  Failing that, attention to
1      details would be useful.
1                          -- _Brian Kernighan_
1 
1    The output of a command can also be piped into 'getline', using
1 'COMMAND | getline'.  In this case, the string COMMAND is run as a shell
1 command and its output is piped into 'awk' to be used as input.  This
1 form of 'getline' reads one record at a time from the pipe.  For
1 example, the following program copies its input to its output, except
1 for lines that begin with '@execute', which are replaced by the output
1 produced by running the rest of the line as a shell command:
1 
1      {
1           if ($1 == "@execute") {
1                tmp = substr($0, 10)        # Remove "@execute"
1                while ((tmp | getline) > 0)
1                     print
1                close(tmp)
1           } else
1                print
1      }
1 
1 The 'close()' function is called to ensure that if two identical
1 '@execute' lines appear in the input, the command is run for each one.
1 ⇒Close Files And Pipes.  Given the input:
1 
1      foo
1      bar
1      baz
1      @execute who
1      bletch
1 
1 the program might produce:
1 
1      foo
1      bar
1      baz
1      arnold     ttyv0   Jul 13 14:22
1      miriam     ttyp0   Jul 13 14:23     (murphy:0)
1      bill       ttyp1   Jul 13 14:23     (murphy:0)
1      bletch
1 
1 Notice that this program ran the command 'who' and printed the result.
1 (If you try this program yourself, you will of course get different
1 results, depending upon who is logged in on your system.)
1 
1    This variation of 'getline' splits the record into fields, sets the
1 value of 'NF', and recomputes the value of '$0'.  The values of 'NR' and
1 'FNR' are not changed.  'RT' is set.
1 
1    According to POSIX, 'EXPRESSION | getline' is ambiguous if EXPRESSION
1 contains unparenthesized operators other than '$'--for example, '"echo "
1 "date" | getline' is ambiguous because the concatenation operator is not
1 parenthesized.  You should write it as '("echo " "date") | getline' if
1 you want your program to be portable to all 'awk' implementations.
1 
1      NOTE: Unfortunately, 'gawk' has not been consistent in its
1      treatment of a construct like '"echo " "date" | getline'.  Most
1      versions, including the current version, treat it at as '("echo "
1      "date") | getline'.  (This is also how BWK 'awk' behaves.)  Some
1      versions instead treat it as '"echo " ("date" | getline)'.  (This
1      is how 'mawk' behaves.)  In short, _always_ use explicit
1      parentheses, and then you won't have to worry.
1