Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I do a recursive find & replace within an SVN checkout?

How do I find and replace every occurrence of:

foo

with

bar

in every text file under the /my/test/dir/ directory tree (recursive find/replace).

BUT I want to be able to do it safely within an SVN checkout and not touch anything inside the .svn directories

Similar to this but now with the SVN restriction: Awk/Sed: How to do a recursive find/replace of a string?

like image 822
Jared Hales Avatar asked Jan 11 '11 22:01

Jared Hales


People also ask

How do you do a recursive search?

Recursive Search To recursively search for a pattern, invoke grep with the -r option (or --recursive ). When this option is used grep will search through all files in the specified directory, skipping the symlinks that are encountered recursively.

Does find command work recursively?

Use the find command to recursively search the directory tree for each specified Path, seeking files that match a Boolean expression written using the terms given in the following text.

How do I search for a directory in recursively?

An easy way to do this is to use find | egrep string . If there are too many hits, then use the -type d flag for find. Run the command at the start of the directory tree you want to search, or you will have to supply the directory as an argument to find as well. Another way to do this is to use ls -laR | egrep ^d .

How do I find recursive strings in Linux?

Use grep to search for lines of text that match one or many regular expressions, and outputs only the matching lines. Using the grep command, we can recursively search all files for a string on a Linux.


1 Answers

There are several possiblities:

Using find:

Using find to create a list of all files, and then piping them to sed or the equivalent, as suggested in the answer you reference, is fairly straightforward, and only requires scanning through the files once.

You'd use one of the same answers as from the question you referenced, but adding -path '*/.svn' -prune -o after the find . in order to prune out the SVN directories. See this question for a discussion of using the prune option with find -- although note that they've got the pattern wrong. Thus, to print out all the files, you would use:

find . -path '*/.svn' -prune -o -type f -print

Then, you can pipe that into an xargs call or whatever to do the individual replacements, as suggested in the question you referenced. There is a lot of discussion there about different options, which I won't reproduce here, although I prefer the version from John Zwinck's answer:

find . -path '*/.svn' -prune -o -type f -exec sed -i 's/foo/bar/g' {} +

Using recursive grep:

If you have a system with GNU grep, you can use that to find the list of files as well. This is probably less efficient than find, but it does allow you to only call sed on the files that match, and I personally find the syntax a lot easier to remember (or figure out from manpages):

sed -i 's/foo/bar/g' `grep -l -R --exclude-dir='*/.svn' 'foo' .`

The -l option causes grep to only output the list of file names, rather than the matching lines.

Using a GUI editor:

Alternately, if you're using windows, do what I do -- get a copy of the NoteTab editor (available in a free version), and use its search-and-replace-on-disk command, which ignores hidden .svn directories automatically and just works.

Edit: Corrected find pattern to */.svn instead of .svn, added more details and some other possibilities. However, this depends on your platform and svn version: .svn without */ may be required in some cases, like on CentOS 7.

like image 182
Brooks Moses Avatar answered Nov 01 '22 14:11

Brooks Moses