Previous | Table of Contents | Next |
As you can see from the last example, you were able to update the prices, but Paech is still misspelled. Say that you need to update fruit_prices.txt with both changes. This means that you have to perform more than one sed command on the file. You can do this in two ways:
As you can guess, the second method is much more efficient and less prone to error because the file is updated only once. You can perform both changes using a single sed command as follows:
sed -e 'command1' -e 'command2' ... -e 'commandN' files
Here command1 through commandN are sed commands of the type discussed previously. These commands are applied to each of the lines in the list of files given by files.
In this case you can perform both updates using either of the following commands:
$ sed -e 's/Paech/Peach/' -e 's/ *[0-9][0-9]*\.[0-9][0-9]$/\$&/' ⇒fruit_prices.txt
Fruit Price/lbs Banana $0.89 Peach $0.79 Kiwi $1.50 Pineapple $1.29 Apple $0.99
To update the file you use the same procedure as before:
$ mv fruit_pieces.txt fruit_pieces.txt.$$ $ sed -e 's/Paech/Peach/' -e 's/ *[0-9][0-9]*\.[0-9][0-9]$/\$&/' ⇒fruit_prices.txt.$$ > fruit_pieces.txt $ cat fruit_pieces.txt Fruit Price/lbs Banana $0.89 Peach $0.79 Kiwi $1.50 Pineapple $1.29 Apple $0.99
As I have mentioned before, if sed does not receive a list of files, it acts on its STDIN. This enables us to use it in pipelines.
I will demonstrate seds usage in this manner by using it to solve the problem of determining the users numeric user ID (uid).
On all UNIX systems the /usr/bin/id command prints the current users uid and gid information. In my case, the output of id looks like the following:
$ /usr/bin/id uid=500(ranga) gid=100(users)
As you can tell from the output, my numeric uid is 500. You need to modify this output so that only this number is printed. Using sed makes this task quite easy.
First you need to eliminate everything following the first parenthesis. You can do that as follows:
$ /usr/bin/id | sed 's/(.*$//'
Now the output looks like the following:
uid=500
If you eliminate the uid= portion at the beginning of the line, you are finished. You can do this as follows:
$ /usr/bin/id | sed -e 's/(.*$//' -e 's/^uid=//'
Now the output is
500
This is what you want. Notice that when you added the second s command, you changed from the single command form for sed to the multiple command form that uses the -e option.
In this chapter you looked at filtering text using regular expressions. Some of the major topics that you covered are
You also covered the similarities between the two most powerful text filtering programs available on UNIX systems, awk and sed. Finally, you looked at using the sed command. Some of the uses that you covered are
In the next chapter I will introduce the awk command and its programming language. Using the material covered in this chapter, you will be able to use awk to easily perform difficult text manipulations.
$ uptime 6:34pm up 2 day(s), 49 min(s), 1 user, load average: 0.00, 0.00, 0.02
load average: 0.05, 0.01, 0.03
Filesystem kbytes used avail capacity Mounted on /dev/dsk/c0t3d0s0 739262 455143 224979 67% / /proc 0 0 0 0% /proc fd 0 0 0 0% /dev/fd /dev/dsk/c0t3d0s1 123455 4813 106297 5% /var /dev/dsk/c0t3d0s5 842150 133819 649381 18% /opt swap 366052 15708 350344 5% /tmp kanchi:/home 1190014 660165 468363 59% /users
-rw-r--r-- 1 ranga users 85 Nov 27 15:34 fruit_prices.txt -rw-r--r-- 1 ranga users 80 Nov 27 13:53 fruit_prices.txt.7880 lrwxrwxrwx 1 ranga users 8 Nov 27 19:01 nash -> nash.txt -rw-r--r-- 1 ranga users 62 Nov 27 16:06 nash.txt lrwxrwxrwx 1 ranga users 8 Nov 27 19:01 urls -> urls.txt -rw-r--r-- 1 ranga users 180 Nov 27 12:34 urls.txt
-rw-r--r-- fruit_prices.txt -rw-r--r-- fruit_prices.txt.7880 -rw-r--r-- nash.txt -rw-r--r-- urls.txt
Previous | Table of Contents | Next |