Find and replace text in files
Substitute one string for another inside a file (or every file in a tree), in place.
How to find and replace text in files in each shell
Bashunix
sed -i 's/old/new/g' file.txtGNU `sed -i` edits in place. On macOS (BSD `sed`) use `sed -i '' 's/old/new/g' file.txt` — the empty arg is the required backup suffix.
Zshunix
sed -i 's/old/new/g' file.txtFishunix
sed -i 's/old/new/g' file.txtPowerShellwindows
(Get-Content file.txt) -replace 'old','new' | Set-Content file.txt`-replace` is regex by default. Use `[regex]::Escape("old")` if `old` may contain regex metacharacters.
cmd.exewindows
powershell -NoProfile -Command "(Get-Content file.txt) -replace 'old','new' | Set-Content file.txt"cmd has no in-place text replace. Shell out to PowerShell — it is on every Windows install since 7.
Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.
Gotchas & notes
- BSD `sed` (macOS default) requires `-i ""` — the empty backup suffix. GNU `sed` (Linux) accepts a bare `-i`. Cross-platform scripts use `sed -i.bak ... && rm *.bak`.
- PowerShell `Set-Content` writes UTF-8 **with BOM** by default on Windows PowerShell 5 — pass `-Encoding utf8NoBOM` (PowerShell 7+) to preserve a clean UTF-8 file.
- Whole-tree replace: bash `find . -type f -name "*.txt" -exec sed -i 's/old/new/g' {} +`; PowerShell `Get-ChildItem -Recurse *.txt | ForEach-Object { (Get-Content $_) -replace 'old','new' | Set-Content $_ }`.
- For multi-line or anchored patterns, prefer `perl -i -pe 's/.../.../g'` (bash) — `sed` regex is line-by-line and lacks lookarounds.