GNU Info

Info Node: (gawk.info)Redirection

(gawk.info)Redirection


Next: Special Files Prev: Printf Up: Printing
Enter node , (file) or (file)node

Redirecting Output of `print' and `printf'
==========================================

   So far, the output from `print' and `printf' has gone to the standard
output, usually the terminal.  Both `print' and `printf' can also send
their output to other places.  This is called "redirection".

   A redirection appears after the `print' or `printf' statement.
Redirections in `awk' are written just like redirections in shell
commands, except that they are written inside the `awk' program.

   There are four forms of output redirection: output to a file, output
appended to a file, output through a pipe to another command, and output
to a coprocess.  They are all shown for the `print' statement, but they
work identically for `printf':

`print ITEMS > OUTPUT-FILE'
     This type of redirection prints the items into the output file
     named OUTPUT-FILE.  The file name OUTPUT-FILE can be any
     expression.  Its value is changed to a string and then used as a
     file name (Note: Expressions).

     When this type of redirection is used, the OUTPUT-FILE is erased
     before the first output is written to it.  Subsequent writes to
     the same OUTPUT-FILE do not erase OUTPUT-FILE, but append to it.
     (This is different from how you use redirections in shell scripts.)
     If OUTPUT-FILE does not exist, it is created.  For example, here
     is how an `awk' program can write a list of BBS names to one file
     named `name-list', and a list of phone numbers to another file
     named `phone-list':

          $ awk '{ print $2 > "phone-list"
          >        print $1 > "name-list" }' BBS-list
          $ cat phone-list
          -| 555-5553
          -| 555-3412
          ...
          $ cat name-list
          -| aardvark
          -| alpo-net
          ...

     Each output file contains one name or number per line.

`print ITEMS >> OUTPUT-FILE'
     This type of redirection prints the items into the pre-existing
     output file named OUTPUT-FILE.  The difference between this and the
     single-`>' redirection is that the old contents (if any) of
     OUTPUT-FILE are not erased.  Instead, the `awk' output is appended
     to the file.  If OUTPUT-FILE does not exist, then it is created.

`print ITEMS | COMMAND'
     It is also possible to send output to another program through a
     pipe instead of into a file.   This type of redirection opens a
     pipe to COMMAND, and writes the values of ITEMS through this pipe
     to another process created to execute COMMAND.

     The redirection argument COMMAND is actually an `awk' expression.
     Its value is converted to a string whose contents give the shell
     command to be run.  For example, the following produces two files,
     one unsorted list of BBS names, and one list sorted in reverse
     alphabetical order:

          awk '{ print $1 > "names.unsorted"
                 command = "sort -r > names.sorted"
                 print $1 | command }' BBS-list

     The unsorted list is written with an ordinary redirection, while
     the sorted list is written by piping through the `sort' utility.

     The next example uses redirection to mail a message to the mailing
     list `bug-system'.  This might be useful when trouble is
     encountered in an `awk' script run periodically for system
     maintenance:

          report = "mail bug-system"
          print "Awk script failed:", $0 | report
          m = ("at record number " FNR " of " FILENAME)
          print m | report
          close(report)

     The message is built using string concatenation and saved in the
     variable `m'.  It is then sent down the pipeline to the `mail'
     program.  (The parentheses group the items to concatenate--see
     Note: String Concatenation.)

     The `close' function is called here because it's a good idea to
     close the pipe as soon as all the intended output has been sent to
     it.  Note: Closing Input and Output Redirections,
 for more information on this.

     This example also illustrates the use of a variable to represent a
     FILE or COMMAND--it is not necessary to always use a string
     constant.  Using a variable is generally a good idea, because
     `awk' requires that the string value be spelled identically every
     time.

`print ITEMS |& COMMAND'
     This type of redirection prints the items to the input of COMMAND.
     The difference between this and the single-`|' redirection is that
     the output from COMMAND can be read with `getline'.  Thus COMMAND
     is a "coprocess", that works together with, but subsidiary to, the
     `awk' program.

     This feature is a `gawk' extension, and is not available in POSIX
     `awk'.  Note: Two-Way Communications with Another Process,
 for a more complete discussion.

   Redirecting output using `>', `>>', `|', or `|&' asks the system to
open a file, pipe, or coprocess, only if the particular FILE or COMMAND
you specify has not already been written to by your program or if it
has been closed since it was last written to.

   It is a common error to use `>' redirection for the first `print' to
a file, and then to use `>>' for subsequent output:

     # clear the file
     print "Don't panic" > "guide.txt"
     ...
     # append
     print "Avoid improbability generators" >> "guide.txt"

This is indeed how redirections must be used from the shell.  But in
`awk', it isn't necessary.  In this kind of case, a program should use
`>' for all the `print' statements, since the output file is only
opened once.

   Many `awk' implementations limit the number of pipelines that an
`awk' program may have open to just one!  In `gawk', there is no such
limit.  `gawk' allows a program to open as many pipelines as the
underlying operating system permits.

Advanced Notes: Piping into `sh'
--------------------------------

   A particularly powerful way to use redirection is to build command
lines, and pipe them into the shell, `sh'.  For example, suppose you
have a list of files brought over from a system where all the file names
are stored in uppercase, and you wish to rename them to have names in
all lowercase.  The following program is both simple and efficient:

     { printf("mv %s %s\n", $0, tolower($0)) | "sh" }
     
     END { close("sh") }

   The `tolower' function returns its argument string with all
uppercase characters converted to lowercase (Note: String Manipulation
Functions.).  The program builds up a list of command
lines, using the `mv' utility to rename the files.  It then sends the
list to the shell for execution.


automatically generated by info2www version 1.2.2.9