You can do a find and replace on files from the Linux shell using the find and sed commands. The first example below shows doing a find and replace only in the current directory while the second example below shows doing a find and replace recursing into subdirectories…
- Replace “www.trendics.com” with “tools.trendics.com” in all html files in the current directory…
- Replace “www.trendics.com” with “tools.trendics.com” in all text files and all subdirectories…
find . -maxdepth 1 -name "*.html" -type f -exec sed -i 's/www.trendics.com/tools.trendics.com/' {} \;
find . -name "*.txt" -type f -exec sed -i 's/www.trendics.com/tools.trendics.com/' {} \;
Here is how this works…
- The dot after the find command specifies to start in the current directory
- The
-maxdepth 1specifies to only include the current directory - The
-name "*.txt"switch specifies to only find txt files - The
-type fspecifies to only match files - The
-exec xyz {} \;specifies to execute xyz for each file where xyz is a sed command specifying to substitute “tools.trendics.com” for “www.trendics.com”
Refer to the documentation on the find and sed for additional options.
Before you run this on your important files, I’d recommend backing up your important files and I’d recommend testing your modified find command in a subdirectory with test files to ensure your find command is working as expected.
Bookmark at:StumbleUpon | Digg | Del.icio.us | Dzone | Newsvine | Spurl | Simpy | Furl | Reddit | Yahoo! MyWeb
Entries (RSS)
thanks for this article. here’s my contribution:
find . [expr] -print0 | xargs -0 sed -i ’s/x/y/g’
handles names with spaces, is more efficient (because it calls sed with as many filenames as possible), and replaces all instances of x on a line (instead of only the first one)
This is why linux sucks. It is completely unusable. Look how complex and intricate this command is. In OS X this kind of thing can be done by a grandmother with a couple of clicks. Meanwhile Linux users will be struggling with man pages, asking on forums and then giving up in frustration.
xargs(1) is your friend. This will require a lot fewer fork(2)/exec(3) calls and will thus run a little faster:
find . -name “*.txt” -type f -print0 | xargs -0 sed -i ‘…’
@josh: Different OSen for different folks… if you don’t like Linux, then you’re certainly free to pick a different OS to work/play with. I like Linux, and I like arcane (and powerful) commands. To each their own.
The man pages are your friend. Instead of using xargs, use + (as opposed to \;) to terminate the -exec clause. It’s faster (for every system I’ve tried it on) than xargs, plus you don’t have to remember the -print0/-0 flags to handle spaces in filenames.
As for OS X being able to do this sort of thing by a grandmother in a couple of clicks… please, describe how. I wouldn’t even know where to start looking to find out how to do this, other than a group-select-and-open followed by an afternoon of search-replace-save-next-file clicking. What’s the magic mouse gestures?
Josh :
Exactly what is the process your grandmother does with a couple of clicks to complete the same in OS X? Besides,you are speaking of GUI interactions and not command line. Linux has a great GUIs also. Do you know any command line tricks in OS X?
Josh (or anyone else for that matter), can you please explain how this can be acheived in OS X in just a couple of clicks? I know text editors have a find an replace, but i do not recall an option i osx to find and replace text in all text files in a directory.
I can do it using Textwrangler in two clicks! Hit cmd-F to get the find option dialog, type in text to find and and the replacement (you also use regx expressions and chose the multi-file option. Under that option, click on the folder you want to process. If you want to add a file filter (restrict to text files) you can set that, then click on “Replace All”.
Mass Find and Replace from Linux Shell…
You can do a find and replace on files from the Linux shell using the find and sed commands. The first example below shows doing a find and replace only in the current directory while the second example below shows doing a find and replace recursing in…
Hmmm…
using Textwrangler means running Textwrangler (presumably it’s in the dock), so that’s one click.
command-F is presumably a shortcut for some menu-option (click to open, click to choose the item), so let’s call it one click-equivalent minimum.
do you need to click in the dialog box in order to give it focus?
choosing the multi-file option would be a click.
adding a file-filter (part of the benefits of ‘find’) would presumably be another click-to-focus if it, too, uses regex, or a bunch more clicks if it’s all GUI, or just one if it’s simply limiting the search-and-replace to text-files only (which isn’t quite as useful as we might hope), so that’s another minimum one click.
clicking on “Replace All” is a click.
I count that as a minimum of five clicks (or, if we’re being generous, four).
It’s amazing that it sorta-kinda works at all, but it seems far more complicated than find has ever been.
. . . . .
What the original article fails to point out is that you can GROW the find command as needed.
You start with selecting just the files you want:
find . -maxdepth 1 -print
then
find -maxdepth 1 -type f -print
then
find -maxdepth 1 -name ‘*.html’ -type f -print
and you say “ah, that looks about right”, and then you start looking for your string:
find -maxdepth -1 -name ‘*.html’ -type f -exec fgrep -l ‘www.trendics.com’ {} \;
and you look at the output and say “Yah, that’s reasonable” so you then look _in_ the files
find -maxdepth -1 -name ‘*.html’ -type f -exec fgrep ‘www.trendics.com’ {} \;
and you scan the output, and don’t twig on something odd (for example, this article would not do well under this substitution), so THEN you do the sed replacement, and all is well in the world, and you’re confident that your task did the right thing with a minimal amount of effort on your part. Sure, the computer worked hard, churning the disk, consuming memory, using up processor cycles… but that’s what the computer is supposed to do, after all. Trade computer effort for assurance that the job was done correctly.
What about
perl -pi.bak -e 's/www.trendics.com/tools.trendics.com/g' *.htmlfor the first? It also makes backups for when you fat finger something. I’ve never needed to use sed since perl does everything nearly as easily and gives you more power when you need it.
Thanks! This worked like a charm and I had been looking for hours to get something like this to do some find & replace work for a google calendar to conky script. Thanks again!!