Sams Teach Yourself Shell Programming in 24 Hours
(Publisher: Macmillan Computer Publishing)
Author(s): Sriranga Veeraraghavan
ISBN: 0672314819
Publication Date: 01/01/99

Previous Table of Contents Next


Look at a few examples to see how to use printf in practice.

Consider the following shell script written with only echo commands:

#!/bin/sh

echo "File Name\tType"

for i in *;
do
   echo "$i\t\c"
    if [ -d $i ]; then
        echo "directory"
    elif [ -h $i ]; then
        echo "symbolic link"
    elif [ -f $i ]; then
        echo "file"
    else
        echo "unknown"
    fi
done

This script produces a table that lists all the visible files in the current directory along with their file type. The output looks similar to the following:

File Name       Type
RCS     directory
dev     directory
humor   directory
images  directory
index.html      file
install directory
java    directory

As you can see, the items in the table’s rows are not lined up with the table headings. You could fix this using spaces and tabs in conjunction with the echo command, but using the printf command makes the task extremely easy.

First, you must determine the format sequence to use. Because the filenames and the column headings are both strings, you need the %s format sequence for formatting. Then you need to pick a maximum size for the filenames. If you pick 32 as the maximum size of your format sequence, the first column becomes %32s. Because you don’t really care about the size of the second column, you can stick with %s for that column. With these changes your script becomes

#!/bin/sh

printf "%32s %s\n" "File Name" "File Type"

for i in *;
do
    printf "%32s " "$i"
    if [ -d "$i" ]; then
        echo "directory"
    elif [ -h "$i" ]; then
        echo "symbolic link"
    elif [ -f "$i" ]; then
        echo "file"
    else
        echo "unknown"
    fi;
done

The output now changes as follows:

                       File Name File Type
                             RCS directory
                             dev directory
                           humor directory
                          images directory
                      index.html file
                         install directory
                            java directory

As you can see, the columns line up but the justification of the first column is incorrect. By adding the - character to the first format sequence, you get the correct sequence %-32s. The script now looks like:

#!/bin/sh

printf "%-32s %s\n" "File Name" "File Type"

for i in *;
do
    printf "%-32s " "$i"
    if [ -d "$i" ]; then
        echo "directory"
    elif [ -h "$i" ]; then
        echo "symbolic link"
    elif [ -f "$i" ]; then
        echo "file"
    else
        echo "unknown"
    fi;
done

The output is now formatted nicely:

File Name                        File Type
RCS                              directory
dev                              directory
humor                            directory
images                           directory
index.html                       file
install                          directory
java                             directory

One thing that you might have noticed about this script is that it uses both printf and echo. Because the printf statements used in this example do not explicitly specify the \n escape sequence, these commands do not produce a newline. To print the newline at the end of each output line, you use echo.

To format numbers, specify a number formatting sequence, such as %f, %e, or %g, instead of the string formatting sequence, %s. One of the questions at the end of this chapter familiarizes you with using number formats.

Output Redirection

In the process of developing a shell script, you often need to capture the output of a command and store it in a file. When the output is in a file, you can edit and modify it easily.


In UNIX, the process of capturing the output of a command and storing it in a file is called output redirection because it redirects the output of a command into a file instead of the screen. To redirect the output of a command or a script to a file, instead of STDOUT, use the output redirection operator, >, as follows:
command > file
list > file

The first form redirects the output of the specified command to a specified file, whereas the second redirects the output of a specified list to a specified file. If file exists, its contents are overwritten; if file does not exist, it is created.

For example, the command

date > now

redirects the output of the date command into the file now. The output does not appear on the terminal, but it is placed into the file instead. If you view the file now, you find the output of the date command:

$ cat now
Sat Nov 14 11:14:01 PST 1998

You can also redirect the output of lists as follows:

{ date; uptime; who ; } > mylog

Here the output of the commands date, uptime, and who is redirected into the file mylog.


Caution:  
When you redirect output to a file using the output redirection operator, the shell overwrites the data in that file with the output of the command you specified. For example, the command
$ date > now

overwrites all the data in the file now with the output of the date command. For this reason, you should take extra care and make sure the file you specified does not contain important information.



Previous Table of Contents Next