gawk: Redirection

1 
1 5.6 Redirecting Output of 'print' and 'printf'
1 ==============================================
1 
1 So far, the output from 'print' and 'printf' has gone to the standard
1 output, usually the screen.  Both 'print' and 'printf' can also send
1 their output to other places.  This is called "redirection".
1 
1      NOTE: When '--sandbox' is specified (⇒Options), redirecting
1      output to files, pipes, and coprocesses is disabled.
1 
1    A redirection appears after the 'print' or 'printf' statement.
1 Redirections in 'awk' are written just like redirections in shell
1 commands, except that they are written inside the 'awk' program.
1 
1    There are four forms of output redirection: output to a file, output
1 appended to a file, output through a pipe to another command, and output
1 to a coprocess.  We show them all for the 'print' statement, but they
1 work identically for 'printf':
1 
1 'print ITEMS > OUTPUT-FILE'
1      This redirection prints the items into the output file named
1      OUTPUT-FILE.  The file name OUTPUT-FILE can be any expression.  Its
11      value is changed to a string and then used as a file name (⇒
      Expressions).
1 
1      When this type of redirection is used, the OUTPUT-FILE is erased
1      before the first output is written to it.  Subsequent writes to the
1      same OUTPUT-FILE do not erase OUTPUT-FILE, but append to it.  (This
1      is different from how you use redirections in shell scripts.)  If
1      OUTPUT-FILE does not exist, it is created.  For example, here is
1      how an 'awk' program can write a list of peoples' names to one file
1      named 'name-list', and a list of phone numbers to another file
1      named 'phone-list':
1 
1           $ awk '{ print $2 > "phone-list"
1           >        print $1 > "name-list" }' mail-list
1           $ cat phone-list
1           -| 555-5553
1           -| 555-3412
1           ...
1           $ cat name-list
1           -| Amelia
1           -| Anthony
1           ...
1 
1      Each output file contains one name or number per line.
1 
1 'print ITEMS >> OUTPUT-FILE'
1      This redirection prints the items into the preexisting output file
1      named OUTPUT-FILE.  The difference between this and the single-'>'
1      redirection is that the old contents (if any) of OUTPUT-FILE are
1      not erased.  Instead, the 'awk' output is appended to the file.  If
1      OUTPUT-FILE does not exist, then it is created.
1 
1 'print ITEMS | COMMAND'
1      It is possible to send output to another program through a pipe
1      instead of into a file.  This redirection opens a pipe to COMMAND,
1      and writes the values of ITEMS through this pipe to another process
1      created to execute COMMAND.
1 
1      The redirection argument COMMAND is actually an 'awk' expression.
1      Its value is converted to a string whose contents give the shell
1      command to be run.  For example, the following produces two files,
1      one unsorted list of peoples' names, and one list sorted in reverse
1      alphabetical order:
1 
1           awk '{ print $1 > "names.unsorted"
1                  command = "sort -r > names.sorted"
1                  print $1 | command }' mail-list
1 
1      The unsorted list is written with an ordinary redirection, while
1      the sorted list is written by piping through the 'sort' utility.
1 
1      The next example uses redirection to mail a message to the mailing
1      list 'bug-system'.  This might be useful when trouble is
1      encountered in an 'awk' script run periodically for system
1      maintenance:
1 
1           report = "mail bug-system"
1           print("Awk script failed:", $0) | report
1           print("at record number", FNR, "of", FILENAME) | report
1           close(report)
1 
1      The 'close()' function is called here because it's a good idea to
1      close the pipe as soon as all the intended output has been sent to
1      it.  ⇒Close Files And Pipes for more information.
1 
1      This example also illustrates the use of a variable to represent a
1      FILE or COMMAND--it is not necessary to always use a string
1      constant.  Using a variable is generally a good idea, because (if
1      you mean to refer to that same file or command) 'awk' requires that
1      the string value be written identically every time.
1 
1 'print ITEMS |& COMMAND'
1      This redirection prints the items to the input of COMMAND.  The
1      difference between this and the single-'|' redirection is that the
1      output from COMMAND can be read with 'getline'.  Thus, COMMAND is a
1      "coprocess", which works together with but is subsidiary to the
1      'awk' program.
1 
1      This feature is a 'gawk' extension, and is not available in POSIX
DONTPRINTYET 1      'awk'.  ⇒Getline/Coprocess, for a brief discussion.  *Note1DONTPRINTYET 1      'awk'.  ⇒Getline/Coprocess, for a brief discussion.  ⇒
      Two-way I/O, for a more complete discussion.
1 
1    Redirecting output using '>', '>>', '|', or '|&' asks the system to
1 open a file, pipe, or coprocess only if the particular FILE or COMMAND
1 you specify has not already been written to by your program or if it has
1 been closed since it was last written to.
1 
1    It is a common error to use '>' redirection for the first 'print' to
1 a file, and then to use '>>' for subsequent output:
1 
1      # clear the file
1      print "Don't panic" > "guide.txt"
1      ...
1      # append
1      print "Avoid improbability generators" >> "guide.txt"
1 
1 This is indeed how redirections must be used from the shell.  But in
1 'awk', it isn't necessary.  In this kind of case, a program should use
1 '>' for all the 'print' statements, because the output file is only
1 opened once.  (It happens that if you mix '>' and '>>' output is
1 produced in the expected order.  However, mixing the operators for the
1 same file is definitely poor style, and is confusing to readers of your
1 program.)
1 
1    Many older 'awk' implementations limit the number of pipelines that
1 an 'awk' program may have open to just one!  In 'gawk', there is no such
1 limit.  'gawk' allows a program to open as many pipelines as the
1 underlying operating system permits.
1 
1                            Piping into 'sh'
1 
1    A particularly powerful way to use redirection is to build command
1 lines and pipe them into the shell, 'sh'.  For example, suppose you have
1 a list of files brought over from a system where all the file names are
1 stored in uppercase, and you wish to rename them to have names in all
1 lowercase.  The following program is both simple and efficient:
1 
1      { printf("mv %s %s\n", $0, tolower($0)) | "sh" }
1 
1      END { close("sh") }
1 
1    The 'tolower()' function returns its argument string with all
1 uppercase characters converted to lowercase (⇒String Functions).
1 The program builds up a list of command lines, using the 'mv' utility to
1 rename the files.  It then sends the list to the shell for execution.
1 
1    ⇒Shell Quoting for a function that can help in generating
1 command lines to be fed to the shell.
1