Wednesday, September 22, 2004 Some in-class exercises in writing short shell scripts. Exercises 1 and 2 are pretty easy; you should be able to handle each of them with relative ease. Exercise 3 is more challenging. If you're having trouble with any of them, please ask for help. 1. Write a script that takes two or more numbers specified as arguments on the command line and uses a 'while' loop to print out each number that is evenly divisible by the first number in the list. % divides 3 5 7 9 11 12 3 9 12 2. Write a script that that takes the name of an existing directory (which we'll refer to as the 'target' directory) as its only argument, creates a new directory named 'images' in the target directory if a directory of that same name doesn't already exist, and then uses a 'foreach' loop to copy every file with extension ".gif" or ".jpg" in the target directory to the 'images' directory. To test your script, create a directory called 'test' and then use the 'touch' command to create a bunch of files with extension ".gif" and ".jpg". 3. Write a script that takes the names of two text files as its only arguments. The first file is just an ordinary text file that might contain, for example, the text of a mail message or a term paper. The second file is of a special form: each line consists of a commonly mispelled word followed by a space followed by the correct spelling of the word, for example % cat mspl.txt tey the teh the arguement argument lawer lawyer plaintif plaintiff Your script should correct the spelling in the ordinary text file using the corrections in the file named by the second argument. For example, % cat msg.txt teh lawer's arguement was pretty weak but tey plaintif still got a big settlement % spellfix msg.txt mspl.txt the lawyer's argument was pretty weak but the plaintiff still got a big settlement Here are some hints that will help in writing your script % set fix = ( `cat mspl.txt` ) % echo "$fix[1] => $fix[2]" tey => the Note that the following straightforward approach to making the substitutions doesn't work: % echo "tey door closed" | sed 's/$foo[1]/$foo[2]/g' tey door closed The problem is that 'sed' has it's own interpretation of $ (it is used in a regular expression to match the end of a line) which is different from the shell's interpretation. Somehow we want to force the shell to 'interpolate' shell variables by looking up their values and inserting the values into the 'sed' command. One solution involves the careful use of quotes. Note that % echo "sed 's/$fix[1]/$fix[2]/g'" sed 's/tey/the/g' The outer double quotes render the inner single quotes as literals - that is to say they don't behave like single quotes usually do in suppressing the interpolation of shell variables. This means that the shell variables do get interpolated. Now we can expand on this and use 'eval' to force evaluation of the quoted string as follows: % eval "echo 'tey door closed' | sed 's/$fix[1]/$fix[2]/g'" the door closed The shell command 'eval' is often used in exactly this fashion. There are many possible solutions to this exercise; I want you to solve this problem using a 'while' loop that repeatedly uses 'sed' to rewrite the input file by making a different substitution on each iteration. Note that you'll probably want to use one or more temporary files to manage this iterative solution.