Code Reference

Find and Replace

Bash · Example / how-to

Find and Replace

Bash · Example / how-to


📋 Overview

Recursively find text files and apply a safe in-place string replacement with find + sed (or perl).

🔧 Core concepts

PieceRole
findSelect files by name/type
sed -iIn-place edit
ExcludesSkip .git / node_modules
Dry runPreview before write

💡 Examples

find_and_replace.sh:

#!/usr/bin/env bash
set -euo pipefail

ROOT="${1:-.}"
OLD="${2:?usage: $0 ROOT OLD NEW}"
NEW="${3:?usage: $0 ROOT OLD NEW}"

echo "dry run matches:"
grep -RIn --exclude-dir=.git --exclude-dir=node_modules --exclude-dir=.venv \
  --include='*.md' --include='*.py' --include='*.ts' --include='*.tsx' \
  -- "$OLD" "$ROOT" || true

read -r -p "Apply replacement? [y/N] " ans
[[ "${ans:-}" =~ ^[Yy]$ ]] || exit 0

# portable-ish in-place with perl
find "$ROOT" \
  \( -path '*/.git/*' -o -path '*/node_modules/*' -o -path '*/.venv/*' \) -prune -o \
  -type f \( -name '*.md' -o -name '*.py' -o -name '*.ts' -o -name '*.tsx' \) \
  -print0 |
  xargs -0 perl -pi -e "s/\Q$OLD\E/$NEW/g"

echo "done"

One-off GNU sed (Linux):

find . -name '*.md' -print0 | xargs -0 sed -i 's/foo/bar/g'

⚠️ Pitfalls

  • macOS sed -i needs sed -i '' — prefer perl -pi for portability.
  • Binary files can be corrupted — limit by extension.
  • Always dry-run with grep before mass edits; commit first.

On this page