sed Across Many Files with find in CI
Combining sed -i with find or a glob rewrites the same pattern across a whole tree of files in one step.
Repo-wide renames and config sweeps are a job for sed plus find. The edit is the easy part; the traps are quoting, the -i flavor split, and accidentally matching too much.
What it does
sed -i edits each file it is given in place. A shell glob or find feeds it the file list, so one command applies the same substitution everywhere. find -exec or xargs scales to large trees and handles awkward filenames.
Common usage
# glob: every yaml file in the directory (GNU sed)
sed -i 's/old/new/g' *.yml
# find -exec for a whole tree, batched
find . -name '*.conf' -exec sed -i 's/old/new/g' {} +
# xargs with NUL-safe filenames
find . -name '*.ini' -print0 | xargs -0 sed -i 's/old/new/g'Options
| Form | What it does |
|---|---|
| sed -i '...' *.ext | Edit every file matching the glob |
| find ... -exec sed -i {} + | Batch many files into few sed calls |
| find -print0 | xargs -0 | Handle names with spaces or newlines |
| -i.bak | Keep a backup of each edited file (GNU) |
| grep -l first | Limit to files that actually contain the pattern |
In CI
On ubuntu-latest, find ... -exec sed -i 's/.../.../ ' {} + is the standard sweep. On macos-latest the same line needs sed -i '' with the empty backup argument, so guard cross-platform sweeps by branching on the OS or installing gnu-sed. Running sed only on files that match (via grep -lZ) avoids rewriting and dirtying files that did not change.
Common errors in CI
On macOS, find -exec sed -i 's/a/b/' {} + fails with sed: 1: "...": invalid command code because BSD -i needs its own argument; insert '' after -i. An empty glob with nullglob off passes the literal *.yml to sed, giving sed: can't read *.yml: No such file or directory. Always scope the pattern so a broad match does not edit unintended files.