Redirection (The GNU Awk User’s Guide)
Next: Special FD, Previous: Printf, Up: Printing [Contents][Index]
5.6 Redirecting Output of print and printf
So far, the output from print
and printf
has gone to the standard output, usually the screen. Both print
and printf
can also send their output to other places. This is called redirection.
NOTE: When
--sandbox
is specified (see section Command-Line Options), redirecting output to files, pipes, and coprocesses is disabled.
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. We show them all for the print
statement, but they work identically for printf
:
print items > output-file
This 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 (see section 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 peoples’ 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" }' mail-list $ cat phone-list -| 555-5553 -| 555-3412 … $ cat name-list -| Amelia -| Anthony …
Each output file contains one name or number per line.
print items >> output-file
This redirection prints the items into the preexisting 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 possible to send output to another program through a pipe instead of into a file. This 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 peoples’ names, and one list sorted in reverse alphabetical order:
awk '{ print $1 > "names.unsorted" command = "sort -r > names.sorted" print $1 | command }' mail-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 print("at record number", FNR, "of", FILENAME) | report close(report)
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. See section Closing Input and Output Redirections for more information.
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 (if you mean to refer to that same file or command) awk
requires that the string value be written identically every time.
print items |& command
This 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, which works together with but is subsidiary to the awk
program.
This feature is a gawk
extension, and is not available in POSIX awk
. See section Using getline from a Coprocess, for a brief discussion. See section 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, because the output file is only opened once. (It happens that if you mix ‘>
’ and ‘>>
’ output is produced in the expected order. However, mixing the operators for the same file is definitely poor style, and is confusing to readers of your program.)
As mentioned earlier (see section Points to Remember About getline), many Many older 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.
Piping into
A particularly powerful way to use redirection is to build command lines and pipe them into the shell, { printf("mv %s %s\n", $0, tolower($0)) | "sh" } END { close("sh") } The See section Quoting Strings to Pass to the Shell for a function that can help in generating command lines to be fed to the shell. |
Next: Special FD, Previous: Printf, Up: Printing [Contents][Index]