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