Suppose you've created a script that you'd like to apply to several files. For example, say that at the end of each day you need to make backup copies of all .html files in your www directory. You could make a backup of each individual .html file, but that's a lot of work. An easier way would be to create a short script to copy an .html file, and then loop (repeat) the script to apply to all .html files in your www directory (Figure 10.5). You create one short script; Unix does the tedious work for you.
Figure 10.5. Using a loop with an embedded command, you can automatically apply a script to several files.
To Make a Loop:
At the shell prompt, start your editor and open the script you want to loop. In this case, we're using vi and the head_ache file. (Of course, you could name the script html -backup or something mundane like that.)
Tell your Unix system which shell to use to run the shell script. In this example, we're telling it (with #!) to run the shell script with /bin/sh.
Make sure that you're in the directory in which the loop will take place. In this example, our shell script resides in our home directory, but the files to which the loop will apply reside in the www directory.
for i in 'ls -1 *.html'
OK, don't panic. Read this as: "Look for items in the list of .html files." In this code, we're providing the output of the embedded command (`ls -1 *.html`) to the for loop (the .html files), as shown in Figure 10.5. The -1 flag on the ls command, by the way, forces a single list of output, which is ideal for script use, rather than several columns, which is easy to read onscreen but doesn't work well for scripts.
On the line immediately after the for statement, type do. This tells the Unix system that the following information will be the loop to apply.
cp $i $i.bak
Here, we copy (cp) the specified items ($i) to a backup file ($i.bak)that is, one backup file per file copied. So, if you have 72 .html files to begin with, you'll end up with those original 72, plus 72 new backup files.
echo "$i backed up!"
Add echo "$i backed up!" so that the system displays onscreen what it has done.
On the next line, announce that you're done with the loop.
Save it, make it executable, and try it out.
This example script will make backup copies of all .html files in the www directory, as in Code Listing 10.4.
Loop instructions can be much more complex. For example, you could make a loop to spell-check each of the chapter files in the directory and report how many misspelled words there are in each file. To do that, use this line in the loop:
echo -e "$i has \t `cat $i | spell | wc -l` misspelled words". Here again just build the loop one step at a time.
Loops are particularly handy for searching and replacing throughout multiple documents. For example, if you're the new Webmaster and want to replace the old Webmaster's name at the bottom of all .html files with your name, you can do so using a loop with sed. Check out Chapter 6 for more information about sed, which introduces sed to loops.
Code Listing 10.4. This loop reports progress as it backs up each file.
[ejr@hobbes scripting]$ more head_ache #! /bin/sh cd ~/www for i in `ls -1 *.html` do cp $i $i.bak echo "$i backed up!" done [ejr@hobbes scripting]$ ./head_ache above.html backed up! file1.html backed up! html.html backed up! reference.html backed up! temp.html backed up! [ejr@hobbes scripting]$