Find and replace with sed in directory and sub directories
320,700
Solution 1
Your find
should look like that to avoid sending directory names to sed
:
find ./ -type f -exec sed -i -e 's/apple/orange/g' {} \;
Solution 2
For larger s&r tasks it's better and faster to use grep and xargs, so, for example;
grep -rl 'apples' /dir_to_search_under | xargs sed -i 's/apples/oranges/g'
Solution 3
Since there are also macOS folks reading this one (as I did), the following code worked for me (on 10.14)
egrep -rl '<pattern>' <dir> | xargs -I@ sed -i '' 's/<arg1>/<arg2>/g' @
All other answers using -i
and -e
do not work on macOS.
Solution 4
This worked for me:
find ./ -type f -exec sed -i '' 's#NEEDLE#REPLACEMENT#' *.php {} \;
Solution 5
grep -e apple your_site_root/**/*.* -s -l | xargs sed -i "" "s|apple|orage|"
Related videos on Youtube
Author by
hd.
Updated on July 08, 2022Comments
-
hd. almost 2 years
I run this command to find and replace all occurrences of 'apple' with 'orange' in all files in root of my site:
find ./ -exec sed -i 's/apple/orange/g' {} \;
But it doesn't go through sub directories.
What is wrong with this command?
Here are some lines of output of
find ./
:./index.php ./header.php ./fpd ./fpd/font ./fpd/font/desktop.ini ./fpd/font/courier.php ./fpd/font/symbol.php
-
Jacob almost 13 yearscould you run
find ./
and post some sample output? And the directory strucuture please. edit: thanks! -
Jacob almost 13 yearsHm your find is correct, works for me with subdirs.
-
carlpett almost 13 yearsHow do you know it does not process subdirectories?
-
hd. almost 13 yearsbecause it gives these errors: sed: couldn't edit ./fpd: not a regular file sed: couldn't edit ./fpd/font: not a regular file sed: couldn't edit ./fpd/font/makefont: not a regula
-
hd. almost 13 yearsoh... i grep for apple and nothing found.they all were replaced. ;) thank you . you opened my eyes !!!
-
tripleee about 8 yearsPossible duplicate of Awk/Sed: How to do a recursive find/replace of a string?
-
user3167101 almost 8 yearsIf using zsh, you can use e.g.
src/**/.js
. -
Yahor M about 6 yearsAnswer you can find here: stackoverflow.com/a/49364510/5578292
-
tripleee almost 5 yearsThe error messages are unnerving, but the command actually does what you want. It's not correct to say it "doesn't work", though it's legitimate and useful to ask how to do this without those warning messages.
-
-
paulmelnikow over 10 yearsYou may need to change
sed -i 's/apple/orange/g'
tosed -i '' 's/apple/orange/g'
to make this work. -
paulmelnikow about 10 years
-i
takes an argument: the extension used to save the temporary file. In GNU sed, looks like there's no space between-i
and its argument, but in BSD sed there is… so BSD-i '' 's/foo/bar/'
is equivalent to GNU-i 's/foo/bar/
. -
paulmelnikow about 10 yearsActually adding
-e
does not work on Mac OS.touch a b c d e
followed by the command above produces a directory listing like this:a a-e b b-e c c-e d d-e e e-e
. -
mrodrigues almost 8 yearsThanks for this answer, it was very helpful! If in a git repository, it's even faster using
git grep -l 'apples' | xargs sed -i 's/apples/oranges/g'
-
phuclv almost 7 yearshe wants to find all files in sub directories contain that string and replace, not only a single file
-
kakoma over 6 yearsFor Mac OS, this answers stackoverflow.com/questions/19242275/… the
RE error: illegal byte sequence
-
Kevin Cherepski about 6 yearsFor fish shell users, be sure to quote the empty braces
'{}'
, because fish automatically expands the empty braces if not quoted. -
Colin D about 6 yearsIs there are shorter version of this? Pretty lengthy. Or a way to make it an alias/bash function?
-
knocte over 5 yearsoriginal question doesn't restrict to *.php files, there's also an .ini one
-
tripleee almost 5 yearsThe unquoted
*.php
is really incorrect; you just got lucky that it didn't get expanded in the starting directory because you didn't happen to have any matching files there. -
aleric over 3 yearsRestriction on file name could be obtained with
-name *.php
on thefind
command. -
cacti5 over 3 yearsIf on macos, use
xargs sed -i '' 's/apples/oranges/g'
-
quantum231 over 2 yearsCan someone please explain what is the -exec and the {} \; at the end?
-
bob dylan over 2 yearsOn the mac the accepted answer does work [kind of] - but it spits out 'duplicate' files with <original-filename>-e which would need to be removed / piped into another command (to use verbatim). This method is better though and is still working for me (on 11.2.3)
-
Colin D over 2 yearscould this be turned into a shortened alias?
-
NessDan about 2 yearsIf you're trying to replace something with a forward slash in it, you can use
sed
with|
rather than/
, e.g.... xargs sed -i 's|mduuid/apples|mduuid/oranges|g'
stackoverflow.com/questions/40714970/…