## 34.20. Making Edits Everywhere Except...

There are two ways in sed to avoid specified portions of a document while making the edits everywhere else. You can use the ! command to specify that the edit applies only to lines that do not match the pattern. Another approach is to use the b (branch) command to skip over portions of the editing script. Let's look at an example.

We've used sed to preprocess the input to troff so that double dashes ( -- ) are converted automatically to em-dashes ( -- ) and straight quotes are converted to curly quotes. However, program examples in technical books are usually shown in a constant-width font that clearly shows each character as it appears on the computer screen. When typesetting a document, we don't want sed to apply the same editing rules within these examples as it does to the rest of the document. For instance, straight quotes should not be replaced by curly quotes.

Because program examples are set off by a pair of macros (something like .ES and .EE, for "Example Start" and "Example End"), we can use those as the basis for exclusion. Here's some sample text that includes an example:

>     .LP
>     The \fItrue\fP command returns a zero exit status.
>     As Joe says, "this is only useful in programming":
>     .ES
>     % \fBtrue\fP
>     % \fBecho "the status was $status"\fP
>     the status was 0
>     .EE

So you can say:

>     /^\.ES/,/^\.EE/!{
>        s/^"/``/
>            ...
>        s/\\(em"/\\(em``/g
>     }

All of the commands enclosed in braces (`{}`) will be subject to the initial pattern address.

There is another way to accomplish the same thing. The b command allows you to transfer control to another line in the script that is marked with an optional label. Using this feature, you could write the previous script like this:

>     /^\.ES/,/^\.EE/bend
>     s/^"/``/
>        ...
>     s/\\(em"/\\(em``/g
>     :end

A label consists of a colon (:) followed by up to seven characters. If the label is missing, the b command branches to the end of the script. (In the example above, the label `end` was included just to show how to use one, but a label is not really necessary here.)

The b command is designed for flow control within the script. It allows you to create subscripts that will be applied only to lines matching certain patterns and not elsewhere. However, as in this case, it also provides a powerful way to exempt part of the text from the action of a single-level script.

The advantage of b over ! for this application is that you can more easily specify multiple conditions to avoid. The ! command can be applied to a single command or to the set of commands, enclosed in braces, that immediately follows. On the other hand, b gives you almost unlimited control over movement around the script.

-- TOR

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