|
|
You can also direct printing into a pipe with a command on the other
end, instead of into a file. The following statement causes the
output of print to be piped into the
command-line:
print | "command-line"
Although we show the command-line and filenames here as literal strings enclosed in quotes, they can also come from variables, and the return values from functions.
Suppose we want to create a list of continent-population pairs, and sort it alphabetically by continent. The awk program below accumulates the population values in the third field for each of the distinct continent names in the fourth field in an array called pop. Then it prints each continent and its population, and pipes this output into the sort command:
BEGIN { FS = "\t" } { pop[$4] += $3 } END { for (c in pop) print c ":" pop[c] | "sort" }Invoked on the file countries, this program yields the following:
Africa:37 Asia:1765 Australia:14 North America:243 South America:142In all of these print statements involving redirection of output, the files or pipes are identified by their names (that is, the pipe above is literally named sort), but they are created and opened only once in the entire run. So, in the last example, for all c in pop, only one sort pipe is open.
In awk, only one pipe may be open at a time. In order to open a second pipe, the first must be closed. The statement close(pipe) closes a pipe, where pipe is the string used to create it in the first place. For example:
close("sort")When opening or closing a file, different strings are different commands.
The special files /dev/stdout and /dev/stderr are particularly useful for printing error messages. To print to the standard error without using /dev/stderr, it is necessary to create a pipe and catenate its output with the standard error of the current shell:
{ ... print "error message" | "cat >&2"; ... }However, using the special files, it is possible to direct standard error and standard output messages appropriately:
{ ... print "error message" > "/dev/stderr"; ... }