## 34.5. sed Addressing Basics

A sed command can specify zero, one, or two addresses. An address can be a line number, a line addressing symbol, or a regular expression (Section 32.4) that describes a pattern.

- If no address is specified, the command is applied to each line.

- If there is only one address, the command is applied to any line matching the address.

- If two comma-separated addresses are specified, the command is performed on the first matching line and all succeeding lines up to and including a line matching the second address. This range may match multiple times throughout the input.

- If an address is followed by an exclamation mark (`!`), the command is applied to all lines that do not match the address.

To illustrate how addressing works, let's look at examples using the delete command, d. A script consisting of simply the d command and no address:

>     d

produces no output since it deletes all lines.

When a line number is supplied as an address, the command affects only that line. For instance, the following example deletes only the first line:

>     1d

The line number refers to an internal line count maintained by sed. This counter is not reset for multiple input files. Thus, no matter how many files were specified as input, there is only one line 1 in the input stream.

Similarly, the input stream has only one last line. It can be specified using the addressing symbol, `$`. The following example deletes the last line of input:

>     $d

The `$` symbol should not be confused with the `$` used in regular expressions, where it means the end of the line.

When a regular expression is supplied as an address, the command affects only the lines matching that pattern. The regular expression must be enclosed by slashes (`/`). The following delete command:

>     /^$/d

deletes only blank lines. All other lines are passed through untouched.

If you supply two addresses, you specify a range of lines over which the command is executed. The following example shows how to delete all lines surrounded by a pair of XHTML tags, in this case, `<ul>` and `</ul>`, that mark the start and end of an unordered list:

>     /^<ul>/,/^<\/ul>/d

It deletes all lines beginning with the line matched by the first pattern up to and including the line matched by the second pattern. Lines outside this range are not affected. If there is more than one list (another pair of `<ul>` and `</ul>` after the first), those lists will also be deleted.

The following command deletes from line 50 to the last line in the file:

>     50,$d

You can mix a line address and a pattern address:

>     1,/^$/d

This example deletes from the first line up to the first blank line, which, for instance, will delete the header from an email message.

You can think of the first address as enabling the action and the second address as disabling it. sed has no way of looking ahead to determine if the second match will be made. The action will be applied to lines once the first match is made. The command will be applied to all subsequent lines until the second match is made. In the previous example, if the file did not contain a blank line, then all lines would be deleted.

An exclamation mark following an address reverses the sense of the match. For instance, the following script deletes all lines except those inside XHTML unordered lists:

>     /^<ul>/,/^<\/ul>/!d

Curly braces (`{}`) let you give more than one command with an address. For example, to search every line of a list, capitalize the word `Caution` on any of those lines, and delete any line with `<br />`:

>     /^<ul>/,/^<\/ul>/{
>         s/Caution/CAUTION/g
>         /<br \/>/d
>     }

-- DD

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