Teach Yourself UNIX Shell Programming in 14 Days

Chapter 11: UNIX Tools in Shell Scripts


This chapter discusses interaction with the user in shell scripts. Objectives important to this chapter are:

  • use of the cut command
  • use of the paste command
  • use of the sed command
  • use of the trap command

The cut command is simply a way of displaying only a part of the information found in some file. It's syntax reflects the fact that, like most UNIX commands it looks at a file one line at a time. The command

cut -c8 filename

would return the 8th character from every line in the file called filename. If we want to see a sequence of characters, we might use

cut -c5-15 filename

which would return the 5th through 15th characters from each line in the file.

If the file is organized into fields, with all fields separated (or delimited) by the same character (like a colon, or a tab), we can tell cut to show us certain fields.

cut -d: -f2,4 filename

tells the cut command that the fields are separated (delimited) by colons, and to return the 2nd and 4th fields in the file called filename.

We can leave out the -d option if the field separator is a tab. The cut command will assume the separator is a tab if not specified.

The paste command combines lines from one file with lines from another file, making a single line out of each pair. That is, it joins the first line from one file with the first line from another file, then joins their second lines, then their third lines, etc. This seems orderly, but you should be sure before using the command that there is a one to one correspondence between the lines in the two files, else you may be lining up information that is unrelated. In the text, the author suggests we

paste parlor phone | sort

where parlor is a list of pizza restaurants, and phone is a list of their phone numbers. It should be obvious that this would only produce a valid list if the two source files were entered in the same order. If we were to sort one file (or both) before using the paste command, it is unlikely that any store's phone number would appear on a line with the correct name. In this, or any other case of sorting data records, always take care to make sure that the entire line is sorted, as above, and not just one column of a data record. It would be like making a list of students, and list of social security numbers, sorting one or both lists, and expecting them to match up correctly when pasted together.

The largest section of this chapter is about the sed command. The name sed stands for stream editor. Again, it edits text streams one line at a time, but it is happy to apply your instructions to each line in several files tirelessly, where a human (or other biological life form) might grow inattentive and error prone.

One method of using sed is from the command line, such as

sed -e "s/text_to_find/text_to_write" filename

The -e option means to read the sed commands entered on the command line (as opposed to -f, which means to read them in a sed script). The quoted text has three parts, separated by slashes. The "s" means to substitute text. The "text_to_find" is the text that sed will search for on each line. The "text_to_write" is the text that will replace the "text_to_find" on each line. Finally, filename could be the name of a specific file to process, or a phrase that expands to many filenames.

The command may also specify a line number or a range of line numbers to process in the named file, however this gets tricky.

sed -e "1,250s/text_to_find/text_to_write" filename

This example means to process the sed substitute command on lines 1 through 250 in filename. If filename above expands to mean several files, then the first one in the list contains lines 1 through x. The second file contains line numbers x+1 through y, the third contains line numbers y+1 through z, and so on. For the purposes of sed, all lines in all files in the list are considered as though they were actually consecutive lines in a single file, with ever increasing line numbers. If we intend to process all lines in the first file, and half the lines in the second file, we had better use the wc command to count the lines first.

Using a sed script file is similar to the section above:

sed -f sedcommands filename

In this example, the -f option means that the next argument is a file of sed commands that are to be processed on the expansion of filename. This is a more modular approach, although it seems a bit less readable than simply putting the commands in the script that we call to start with.

The sed command also has a delete option. Remember that, being a line editor, it deletes entire lines. With that in mind, you can use

sed -e "10,15d" filename

to delete lines 10 through 15 in the expansion of filename.

The trap command waits for a specified signal from the system to execute another command. The syntax is

trap "command to execute on signal" signals

This is explained well by Professor Brown on the CIT web site (unix14.htm). The command placed in quotes will be executed when the system generates any signal specified by the programmer. For example,

trap "echo Gotcha" 1 2 9

this command would wait for system signals 1, 2 or 9 to be generated, and then echo "Gotcha" to the screen. The signals listed by Professor Brown are

0	exit from the shell
2	INTERRUPT character
11	segmentation violation
15	software termination

Any of these might be trapped with the trap command.