Flow Control

Labels and b — branch unconditionally
cat <<'EOF' > /tmp/branch-b.txt
keep this
skip this REMOVE
keep this too
also REMOVE this
final line
EOF
# /REMOVE/b skip jumps to :skip label, bypassing the print
sed -n '/REMOVE/b skip; p; :skip' /tmp/branch-b.txt
t — branch if last substitution succeeded
cat <<'EOF' > /tmp/branch-t.txt
item: apple
item: banana_split
item: cherry
item: date_palm_tree
EOF
# t loops back if s/// succeeded — replaces all underscores with spaces
sed ':loop; s/_/ /; t loop' /tmp/branch-t.txt
Loop: replace first occurrence repeatedly until all gone
# Without /g flag — t loops s/// until no more matches (same effect as /g)
echo 'aaa-bbb-ccc-ddd' | sed ':a; s/-/./; t a'
Accumulate entire file into pattern space — :a;N;$!ba idiom
cat <<'EOF' > /tmp/slurp-branch.txt
line one
line two
line three
line four
EOF
# Classic idiom: label a, append Next line, if Not last branch to a
# Then operate on the whole file at once
sed ':a;N;$!ba;s/\n/,/g' /tmp/slurp-branch.txt
Process blocks between markers using branching
cat <<'EOF' > /tmp/block-branch.txt
normal text
BEGIN_BLOCK
  transform this
  and this
END_BLOCK
more normal text
BEGIN_BLOCK
  also transform
END_BLOCK
final text
EOF
# Between markers: uppercase content; branch past transform for other lines
sed '/BEGIN_BLOCK/,/END_BLOCK/{/BEGIN_BLOCK/b;/END_BLOCK/b;s/.*/\U&/}' /tmp/block-branch.txt
Sed script file — save commands to file, run with -f
cat <<'SCRIPT' > /tmp/transform.sed
# Remove comments
/^#/d
# Normalize whitespace
s/[[:space:]]\{2,\}/ /g
# Uppercase first word
s/^\([a-z]\)/\U\1/
SCRIPT

cat <<'EOF' > /tmp/input-for-script.txt
# this is a comment
hello    world
foo   bar   baz
# another comment
testing   one two
EOF

sed -f /tmp/transform.sed /tmp/input-for-script.txt
Multiple -e scripts chained — order matters
cat <<'EOF' > /tmp/chain.txt
error: disk full
warning: high cpu
error: network down
info: all clear
warning: low memory
EOF
# First -e tags errors; second -e tags warnings; order is sequential
sed -e 's/^error:/[CRITICAL]/' -e 's/^warning:/[WARN]/' -e 's/^info:/[OK]/' /tmp/chain.txt
Print nth occurrence of a pattern using branching counter
cat <<'EOF' > /tmp/nth.txt
apple
banana
cherry
apple
date
apple
fig
apple
EOF
# Print the 3rd occurrence of "apple" — uses hold space as counter
sed -n '/apple/{x;s/i/&i/;/^iii$/{x;p;q};x}' /tmp/nth.txt
Delete duplicate adjacent lines (uniq replacement)
cat <<'EOF' > /tmp/dedup.txt
alpha
alpha
beta
beta
beta
gamma
alpha
alpha
EOF
# Hold previous line; compare with current; skip if same
sed '$!N;/^\(.*\)\n\1$/!P;D' /tmp/dedup.txt