## 20.7. ed/ex Batch Edits: A Typical Example

What ed and ex lack in intutitive interface design, they make up for when used in batch editing shell scripts. For example, you might be maintaining a web site with a lot of static content all stored in traditional HTML files. One such file might look like this:

>     <html>
>     <body>
>     <h1>Hello, world!</h1>
>     <p>Glad you could make it
>     <img src="/graphics/smiley.gif" alt="[:-)]">.
>     <p>Here's a picture of my house:
>     <img src="/graphics/house.gif" alt="[my house]">
>     </body>
>     </html>

One day, you get an email that all the images will now be served out of the directory /img instead of /graphics. Also, all existing gif files have been replaced with `png` files. Although these changes don't sound like much, making these modifications to a large number of files quickly becomes tedious. By writing a shell script that calls either ed or ex, you will not only solve today's problem, but you'll also be ready to make new changes to the files whenever that becomes necessary. A Bourne shell script that makes these changes looks like the following:

>     #!/bin/sh
>     # Convert some of the hard coded values in HTML
>     # into the new site schema

>     # Patterns to be replaced
>     old_graphics_dir="graphics"
>     old_graphics_ext="gif"

>     # new values
>     new_graphics_dir="img"
>     new_graphics_ext="png"

>     # Make the changes
>     for file in *html;
>     do
>        ed $file <<EOF
>     1,\$s/$old_graphics_dir/$new_graphics_dir/g
>     1,\$s/$old_graphics_ext/$new_graphics_ext/g
>     w
>     EOF
>     done

The script is fairly simple. It defines a few variables to hold the patterns to be found and replaced. The replacement values are defined next. This script is meant to be run in the directory containing all the HTML files. The list of all files ending in "html" is iterated over in a `for` loop in which ed is fed commands from a here document. Recall that `$` is a special character for Bourne shell and must be escaped in the line-addressing part of the ed command. After the search and replace operations finish, the ed buffers need to be written back to disk with the `w` command. This script works with both ed and ex.

In older versions of ed, you may find that if the first pattern doesn't match, ed doesn't even try the second pattern. If your version does this, one workaround suggested by Chris Torek is to use the global command `g` like this:

>     ed - $i << end
>     g/$old_graphics_dir/s//$new_graphics_dir/g
>     g/$old_graphics_ext/s//$new_graphics_ext/g
>     w
>     end

The addition of the `-` suppresses the two numbers that ed normally prints.

-- CT and JJ

Copyright © 2003 O'Reilly & Associates. All rights reserved.