6.4 Branching and Flow Control

The branching commands b, t, and T enable changing the flow of sed programs.

By default, sed reads an input line into the pattern buffer, then continues to processes all commands in order. Commands without addresses affect all lines. Commands with addresses affect only matching lines. See How sed Works and Addresses overview.

sed does not support a typical if/then construct. Instead, some commands can be used as conditionals or to change the default flow control:

d

delete (clears) the current pattern space, and restart the program cycle without processing the rest of the commands and without printing the pattern space.

D

delete the contents of the pattern space up to the first newline, and restart the program cycle without processing the rest of the commands and without printing the pattern space.

[addr]X
[addr]{ X ; X ; X }
/regexp/X
/regexp/{ X ; X ; X }

Addresses and regular expressions can be used as an if/then conditional: If [addr] matches the current pattern space, execute the command(s). For example: The command /^#/d means: if the current pattern matches the regular expression ^# (a line starting with a hash), then execute the d command: delete the line without printing it, and restart the program cycle immediately.

b

branch unconditionally (that is: always jump to a label, skipping or repeating other commands, without restarting a new cycle). Combined with an address, the branch can be conditionally executed on matched lines.

t

branch conditionally (that is: jump to a label) only if a s/// command has succeeded since the last input line was read or another conditional branch was taken.

T

similar but opposite to the t command: branch only if there has been no successful substitutions since the last input line was read.

The following two sed programs are equivalent. The first (contrived) example uses the b command to skip the s/// command on lines containing ‘1’. The second example uses an address with negation (‘!’) to perform substitution only on desired lines. The y/// command is still executed on all lines:

$ printf '%s\n' a1 a2 a3 | sed -E '/1/bx ; s/a/z/ ; :x ; y/123/456/'
a4
z5
z6

$ printf '%s\n' a1 a2 a3 | sed -E '/1/!s/a/z/ ; y/123/456/'
a4
z5
z6