objectif
Remplacer une chaîne ou une expression régulière dans des fichiers sans casser la compatibilité Linux/macOS et sans corrompre les fichiers.
code minimal
# portable: écrire via un fichier temporaire puis remplacer (atomique)
tmp="$(mktemp)"; sed -E 's/old/new/g' config.ini > "$tmp" && mv -f "$tmp" config.ini
utilisation
# GNU/Linux: in-place avec sauvegarde, puis suppression du .bak
sed -E -i.bak 's/old/new/g' config.ini && rm -f config.ini.bak
# macOS/BSD: in-place exige un suffixe (même commande que ci-dessus)
sed -E -i.bak 's/old/new/g' config.ini && rm -f config.ini.bak
# plusieurs fichiers: sûr avec find -print0 / xargs -0
find . -type f -name "*.env" -print0 \
| xargs -0 -I{} sh -c 'set -Eeuo pipefail; sed -E -i.bak "s/^DEBUG=.*/DEBUG=false/" "$1"' sh {}
# remplacer seulement s'il y a correspondance (évite de toucher l'mtime inutilement)
grep -q 'old' config.ini && { tmp="$(mktemp -p . .config.ini.XXXXXX)"; sed -E 's/old/new/g' config.ini > "$tmp" && mv -f "$tmp" config.ini; }
# remplacer une barre oblique sans échapper (changer le délimiteur)
sed -E 's|/api/v1/|/api/v2/|g' routes.txt
variante(s) utile(s)
# mots entiers uniquement
# GNU sed:
sed -E 's/\<token\>/secret/g' app.conf
# BSD/macOS sed:
sed -E 's/[[:<:]]token[[:>:]]/secret/g' app.conf
# ignorer la casse
sed -E 's/foo/bar/Ig' fichier.txt
# capturer et réutiliser (groupes)
sed -E 's/^version=([0-9]+)\.([0-9]+)\.([0-9]+)/version=\1.\2.'"$((PATCH+1))"'/'
# n'agir que sur des lignes matching un préfixe
sed -E '/^PORT=/ s/[0-9]+/8080/' .env
# remplacer entre délimiteurs (ex: balises)
sed -E '/^BEGIN CONFIG$/,/^END CONFIG$/ s/^#?enabled=.*/enabled=true/'
notes
- pour la portabilité, évitez
sed -isans suffixe sur macOS; utilisez-i.bakpuis supprimez la sauvegarde, ou la stratégiemktemp+mv. -Eactive les regex étendues; adaptez vos motifs en conséquence (escapes plus simples).- préférez un délimiteur alternatif (
|) lorsque votre motif contient des/. \</\>(mots entiers) est propre à GNU sed; sur BSD/macOS, utilisez[[:<:]]et[[:>:]].- l’approche via
mktemp+mvest atomique si le temporaire est créé sur le même filesystem (utilisez-p .pour le dossier courant).