Once a SED transformation grows beyond a one-liner, it belongs in a script file. The -f flag loads SED commands from a file, enabling version control, reuse, and comments. Combined with find and xargs, a SED script file becomes a fleet-wide config transformation tool.
1
SED script files — structure and invocation
SED
#!/usr/bin/env sed -f
# normalise_config.sed — Clean and normalise config files
# Usage: sed -f normalise_config.sed input.conf
# sed -f normalise_config.sed -i input.conf (in-place)
#
# Comments in .sed files use #
# Each line is a sed command; semicolons separate inline commands
# ── Remove comment lines and blank lines ──────────────────
/^[[:space:]]*#/d
/^[[:space:]]*$/d
# ── Trim whitespace ───────────────────────────────────────
s/^[[:space:]]*//
s/[[:space:]]*$//
# ── Normalise = spacing (key=val, key = val → key=val) ────
s/[[:space:]]*=[[:space:]]*/=/
# ── Uppercase section headers ─────────────────────────────
/^\[/{
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
}
# ── Substitute known legacy key names ─────────────────────
s/^DB_SERVER=/DB_HOST=/
s/^DATABASE_NAME=/DB_NAME=/
s/^MYSQL_PASSWORD=/DB_PASS=/
2
Composing multiple script files
BASH
# ── Apply multiple .sed files in sequence ─────────────────
sed -f strip_comments.sed -f normalise_keys.sed -f update_values.sed config.env
# ── Mix -f files with -e inline commands ─────────────────
sed -f base_transforms.sed -e "s/old_host/${NEW_HOST}/g" template.conf
# ── sed script files directory — managed library ──────────
ls /etc/myapp/sed-rules/
# 01_strip_legacy.sed
# 02_normalise_keys.sed
# 03_set_defaults.sed
# 04_validate_values.sed
apply_transforms() {
local file="${1}"
local args=()
for script in /etc/myapp/sed-rules/*.sed; do
args+=(-f "${script}")
done
sed "${args[@]}" "${file}"
}
apply_transforms /etc/myapp/config.env > /tmp/config.env.new
diff /etc/myapp/config.env /tmp/config.env.new
mv /tmp/config.env.new /etc/myapp/config.env
3
Batch in-place editing across many files
BASH
# ── Update all config files in a directory ────────────────
find /etc/myapp -name "*.conf" -type f \
-exec sed -i 's/old-host/new-host/g' {} +
# ── Update all files but only if the pattern exists (faster)
grep -rl "old-host" /etc/myapp/ | \
xargs sed -i 's/old-host/new-host/g'
# ── Batch update with backup ──────────────────────────────
find /etc -name "*.conf" -exec sed -i.bak '
s/DB_HOST=.*/DB_HOST=prod-db-01/
s/DB_PORT=.*/DB_PORT=5432/
' {} +
# ── Version bump across all script files ─────────────────
find /opt/myapp/bin -type f -name "*.sh" | \
xargs grep -l "VERSION=" | \
xargs sed -i -E \
's/(^readonly VERSION=")[0-9]+\.[0-9]+\.[0-9]+(")/\12.2.0\2/'
# ── Apply sed script file across entire codebase ──────────
find /opt/myapp -type f \( -name "*.conf" -o -name "*.env" \) \
-exec sed -i -f /opt/myapp/scripts/migrations/v2.sed {} +
# ── Dry run first — pipe through sed without -i ───────────
find /etc/nginx -name "*.conf" | while read -r f; do
diff "${f}" <(sed 's/old/new/g' "${f}") && echo " No changes: ${f}"
done
4
SED for templating and config generation
BASH
#!/usr/bin/env bash
# deploy_config.sh — Generate per-environment configs from template
set -euo pipefail
TEMPLATE="/opt/myapp/config/app.conf.template"
ENV="${1:?Usage: deploy_config.sh ENV}"
# Load env-specific values
source "/opt/myapp/config/${ENV}.env"
# Generate config via sed substitution
sed "
s|{{DB_HOST}}|${DB_HOST}|g
s|{{DB_PORT}}|${DB_PORT:-3306}|g
s|{{DB_NAME}}|${DB_NAME}|g
s|{{APP_ENV}}|${ENV}|g
s|{{LOG_LEVEL}}|${LOG_LEVEL:-INFO}|g
s|{{CACHE_TTL}}|${CACHE_TTL:-300}|g
/{{[A-Z_]*}}/d # delete any unfilled placeholders
" "${TEMPLATE}" > "/etc/myapp/${ENV}.conf"
# Verify no placeholders remain
if grep -q '{{.*}}' "/etc/myapp/${ENV}.conf"; then
echo "ERROR: Unfilled placeholders remain" >&2
exit 1
fi
echo " ✔ Config generated for ${ENV}: /etc/myapp/${ENV}.conf"
vriddh@prod-01:~/scripts$grep -rl "old-db-01" /etc/myapp/ | xargs sed -i 's/old-db-01/prod-db-01/g'
✔ Updated 4 files
vriddh@prod-01:~/scripts$./deploy_config.sh production
✔ Config generated for production: /etc/myapp/production.conf
vriddh@prod-01:~/scripts sed -f normalise_config.sed -i /etc/myapp/*.conf && echo "All normalised"
All normalised
█
✔ SED scripts and files — Store multi-command SED programs in
.sed files run with sed -f script.sed. Compose pipelines with multiple -f files. Use grep -rl pattern | xargs sed -i — far faster than running sed on every file when only a few need changes. Always dry-run with diff file <(sed 's/old/new/' file) before using -i on production configs. Use double-quoted sed scripts when you need shell variable expansion.