in reply to Search & Replace in subdirectory files

If you're on a unix-like system, you can use plain old find to find all files in this directory or subdirectories, then use perl with "-i" and "-p" to operate on each of them:

find . -type f \! -name '*.bak' -print0 | \ xargs -0 perl -i.bak -plwe 's/foo/bar/g'

Modify the arguments to find as appropriate. This is especially nice if you are only performing this substitution on ".html" or ".txt" files, as that removes the need to check for ".bak" files. For example, if you only want to edit files ending with ".html":

find . -type f -name '*.html' -print0 | \ xargs -0 perl -i.bak -plwe 's/foo/bar/g'

Also, some older / vendor-supplied versions of find and xargs don't have -print0 and -0; you can just use -print on the find, and remove the -0 from the xargs argument list. (They are there for added security, in case you have files with newlines in their names.)

If you are on a non-unix system, the File::Find approaches should work. (Or you can instally Cygwin etc.)

Finally, the details of the perl flags there are described in perlrun; the important one here is "-i.bak", which makes a copy of each file named on the command line then modifies the original in-place (or so you can consider it; more likely, it renames the original to the backup filename, then reads from the backup, operates on the contents, then writes to the original filename).

So, this perl command:

perl -i.bak -plwe 's/foo/bar/g' file1.txt file2.txt file3.txt

Is roughly equivalent to this shell loop:

for i in file1.txt file2.txt file3.txt do mv $i $i.bak perl -plwe 's/foo/bar/g' < $i.bak > $i done

(Yes, I know that the input redirection is unnecessary there; I left it in so that it is more obvious that perl is being used as a filter.)

Replies are listed 'Best First'.
Re: Re: Search & Replace in subdirectory files
by ctilmes (Vicar) on Apr 24, 2004 at 10:39 UTC
    if your grep does recursion, you can even use it to find the files:
    perl -i.bak -plwe 's/foo/bar/g' `grep -r -l foo .`