Node:Redirection, Next:Special Files, Previous:Printf, Up:Printing
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
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
>
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
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's then sent down the pipeline to the mail
program.
(The parentheses group the items to concatenate--see
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.
See 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 awk
requires that the string value be spelled identically
every time.
print items |& command
|
redirection is that the output from command
can be read with getline
.
Thus command is a coprocess, which works together with,
but subsidiary to, the awk
program.
This feature is a gawk
extension, and is not available in
POSIX awk
.
See 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.
As mentioned earlier
(see Points About getline
to Remember),
many
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.
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
(see 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.