// DevOps
Safe Find & Replace: How Not to Break Binaries
Published on 2026-09-22
When working with real projects (changing a CDN, migration, refactoring) you often need to replace one URL with another in bulk.
At first glance the task seems trivial: sed -i 's|old|new|g' **/* — and you’re done.
In practice this approach is dangerous: the pattern can match binary files.
Careless replacement leads to:
- corruption of binary files (images, PDFs, archives);
- unnecessary changes in git history: binaries are marked as modified;
- inability to roll back if no backup was made.
Below is a procedure that changes only text, leaves binaries untouched, and creates a targeted backup before replacement.
Input data
- Old URL:
https://static-old.example-cdn.net - New URL:
https://cdn-new.example-storage.net - Context: Project with mixed content (HTML, JS, YAML + PNG, JPG, WOFF2).
Procedure
1. Preparation and search (Dry Run)
The key tool is grep -I (ignores binary files even if they contain matching bytes).
First, just see what we are going to change:
# Search recursively, ignore binaries, print list of files
grep -rIl 'https://static-old.example-cdn.net' .Important: make sure the list contains only text files (no images, fonts, etc.). If everything looks reasonable — proceed.
2. Targeted backup
Don’t copy the entire project — it’s slow and takes space. Save only the files that contain the searched string, preserving hierarchy and metadata.
SEARCH="https://static-old.example-cdn.net"
BACKUP_DIR="backup_before_replace"
mkdir -p "$BACKUP_DIR"
# Copy only files that match
find . -type f -print0 \
| xargs -0 grep -Il "$SEARCH" \
| xargs -I{} sh -c 'mkdir -p "$BACKUP_DIR/$(dirname "{}")" && cp -p "{}" "$BACKUP_DIR/{}"'Now backup_before_replace contains an exact copy of only the files to be changed. Rollback is a simple copy back.
3. Replacement
sed -i behaves differently on Linux (GNU) and macOS (BSD):
- Linux:
sed -i 's/old/new/g' - macOS:
sed -i '' 's/old/new/g'
To make the script work everywhere (locally, in CI, on Mac/Linux), use perl — it is identical on all *nix systems.
OLD="https://static-old.example-cdn.net"
NEW="https://cdn-new.example-storage.net"
find . -type f -not -path "./$BACKUP_DIR/*" -print0 \
| xargs -0 grep -Il "$OLD" \
| xargs -0 perl -pi -e "s|\Q$OLD\E|$NEW|g"\Q and \E automatically escape all special characters in the URL (dots, slashes, hyphens) — no need to backslash them manually.
4. Verification
Make sure everything went successfully:
# Should return empty output
grep -rIl "$OLD" . --exclude-dir="$BACKUP_DIR"
# Should show changed files (example: first 5)
grep -rIl "$NEW" . --exclude-dir="$BACKUP_DIR" | head -n 5You can also run git status or git diff --stat to see the actual changes.
Why this is more reliable
grep -I— reliable protection from corrupting binaries.- Targeted backup — save only the delta, saving space and time.
perlinstead ofsed— cross-platform stability (Linux, macOS, CI).- Variables and clear steps — the script is easy to read and adapt.
TL;DR — Ready snippet for “here and now”
Paste into the terminal and replace the URLs:
SEARCH="https://static-old.example-cdn.net"
REPLACE="https://cdn-new.example-storage.net"
BACKUP="backup_$(date +%s)"
mkdir -p "$BACKUP"
# 1. Targeted backup of only files that match
find . -type f -print0 \
| xargs -0 grep -Il "$SEARCH" \
| xargs -I{} sh -c 'mkdir -p "$BACKUP/$(dirname "{}")" && cp -p "{}" "$BACKUP/{}"'
# 2. Safe replacement (perl — works on Linux and macOS)
find . -type f -not -path "./$BACKUP/*" -print0 \
| xargs -0 grep -Il "$SEARCH" \
| xargs -0 perl -pi -e "s|\Q$SEARCH\E|$REPLACE|g"
echo "Done! Backup saved in folder $BACKUP"
echo "Rollback (if needed): cp -r $BACKUP/. ."This approach is safe and works the same across all files: changes affect only text, while binary data remains untouched.
// Reviews
Related reviews
I came with an expensive request to configure a VPS server, but during the consultation Mikhail suggested a much simpler, more affordable solution. In the end I saved time and money. Mikhail — a true expert who works for the client's result, not for the fee. I recommend him!
I came with an expensive request to configure a VPS server, but during the consultation Mikhail suggested a much simpler and more cost-effective solution. In the end I saved budget and time. Mikhail — a true expert who …
VPS setup, server setup
2026-05-12 · ★ 5/5
Excellent work! Set up the server very quickly, installed the control panel, and configured the IP. Definitely recommend!
Excellent work! Very quickly set up the server, installed the panel, configured the IP I can definitely recommend it!
Everything was excellent; helped promptly and professionally. Thank you — I recommend them to the community.
Everything's great, helped promptly and professionally, thank you, I recommend it to the community
VPS setup, server setup
2026-04-16 · ★ 5/5
There were several issues concerning both the technical side and overall understanding. Mikhail responded quickly, resolved the technical problems, and helped me understand them — many thanks. I'm satisfied with the result.
There were several issues concerning both the technical side and overall understanding. Mikhail responded quickly to the request, helped sort things out and resolved the technical problems and helped clarify …
VPS setup, server setup
2026-02-18 · ★ 5/5
Everything was done quickly and efficiently. I recommend.
Everything was done quickly and efficiently. I recommend.
VPS setup, server setup
2026-01-17 · ★ 5/5
Everything went well; the contractor responded quickly to questions and helped resolve the issue. Thanks!
Everything went well, the contractor responded quickly to questions and helped resolve the issue. Thank you!
VPS setup, server setup
2025-12-16 · ★ 5/5
// Contact
Need help?
Get in touch with me and I'll help solve the problem
I reply within one business day (03:00-13:00 GMT)
Или оставьте заявку здесь:
// Related