Capture Groups

Extract value from key=value pair
cat <<'EOF' > /tmp/app.conf
database_host=10.50.1.50
database_port=5432
database_name=domus
log_level=debug
EOF
sed -n 's/^database_host=\(.*\)/\1/p' /tmp/app.conf
Extract IP addresses from log lines
cat <<'EOF' > /tmp/auth.log
Apr 11 08:14:22 modestus-aw sshd[1234]: Accepted publickey for evan from 10.50.1.100 port 52341
Apr 11 08:14:23 modestus-aw sshd[1235]: Failed password for root from 192.168.1.50 port 52342
Apr 11 08:15:01 modestus-aw sshd[1236]: Accepted publickey for evan from 10.50.1.20 port 52343
EOF
sed -n 's/.*from \([0-9.]*\) port.*/\1/p' /tmp/auth.log
Extract hostnames from SSH config
cat <<'EOF' > /tmp/ssh_config
Host ise-01
    HostName ise-01.inside.domusdigitalis.dev
Host ad-dc
    HostName ad-dc.inside.domusdigitalis.dev
Host pfsense
    HostName 10.50.1.1
EOF
sed -n 's/^Host \([^ ]*\)/\1/p' /tmp/ssh_config
Strip YAML key — extract value after colon
cat <<'EOF' > /tmp/config.yml
name: domus-captures
version: 1.0.0
prerelease: false
title: Captures
EOF
sed -n 's/^version: *\(.*\)/\1/p' /tmp/config.yml
Extract text between delimiters — square brackets
cat <<'EOF' > /tmp/log.txt
[INFO] Server started on port 443
[ERROR] Connection refused to 10.50.1.50
[WARN] Certificate expires in 7 days
[ERROR] Authentication failed for user admin
EOF
sed -n 's/^\[\([^]]*\)\].*/\1/p' /tmp/log.txt
Extract URLs from HTML
cat <<'EOF' > /tmp/links.html
<a href="https://docs.domusdigitalis.dev">Documentation</a>
<a href="https://github.com/domus/captures">Repository</a>
<a href="https://vault.inside.domusdigitalis.dev">Vault</a>
EOF
sed -n 's/.*href="\([^"]*\)".*/\1/p' /tmp/links.html
Extract Antora component name from antora.yml
cat <<'EOF' > /tmp/antora.yml
name: captures
title: Captures
version: ~
nav:
  - modules/ROOT/nav.adoc
EOF
sed -n 's/^name: *\(.*\)/\1/p' /tmp/antora.yml
Extract multiple capture groups — reformat date
echo '2026-04-11' | sed 's/\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\)/\3\/\2\/\1/'
Extract with ERE — cleaner capture group syntax
cat <<'EOF' > /tmp/auth.log
Apr 11 08:14:22 sshd[1234]: Accepted publickey for evan from 10.50.1.100
Apr 11 08:14:23 sshd[1235]: Failed password for root from 192.168.1.50
EOF
sed -En 's/.*for ([^ ]+) from ([0-9.]+)/user=\1 ip=\2/p' /tmp/auth.log

Extract Man Page Sections

# Extract a named section from any man page
# col -b strips backspace control chars from man page formatting
# sed -n '/start/,/end/p' prints lines between two patterns

man bash  | col -b | sed -n '/Here Documents/,/^[A-Z]/p'    (1)
man bash  | col -b | sed -n '/Here Strings/,/^[A-Z]/p'      (2)
man bash  | col -b | sed -n '/Word Splitting/,/^[A-Z]/p'
man bash  | col -b | sed -n '/Parameter Expansion/,/^[A-Z]/p'
man find  | col -b | sed -n '/TESTS/,/^[A-Z]/p'
man chmod | col -b | sed -n '/MODES/,/^[A-Z]/p'
man curl  | col -b | sed -n '/OPTIONS/,/^[A-Z]/p'
1 /^[A-Z]/ matches the next ALL-CAPS section heading — stops extraction there
2 Range pattern — prints everything between the two matches inclusive

/^[A-Z]/ works because man bash section headings are ALL CAPS at column 0. If extraction stops too early or too late, adjust the end pattern. For man pages with different heading styles try /^[A-Z][A-Z]/.