Change strings in multiple files in directory tree

I ran into a little problem where I had to move a clients web site to a new server. Unfortunately, the directory structure had changed where the DocumentRoot originally had been /home/hosting/webs/clientname/website/web to /var/www/website/web.

This particular site had several dozen .htaccess files, all of them pointing to the absolute directory path.

Thanks to the aid of this web site, I was able to come up with a solution, use grep and xargs to process each file found.

The best solution was:

grep -lr -e 'string_to_look_for' path/to/root/of/tree | xargs perl -p -i.bak -e ’s/string_to_look_for/string_to_replace_it_with/g’ *

This NOTE: the -i.bak in the Perl command makes a backup of the file before it is processed.

In my case, I was looking for the string /home/hosting/webs/clientname/website/web, which contains the forward slash (/) so I could not use the standard regex forward slash perl normally wants. However, you can use just about any delimiter here, so I chose a pipe (|). My result was:

grep -lr -e '/home/hosting/webs/' /var/www/domainname/web/* | xargs perl -p -i.bak -e 's|/home/hosting/webs/client/domain/web|/var/www/domain/web/|g'

Breaking this down:

  • grep -lr -e '/home/hosting/webs/' /var/www/domainname/web/ -- Look in all files under /var/www/domainname/web (recursively) for any content matching '/home/hosting/webs' and pass the file name to STDOUT
  • xargs -- This is the greatest command. Takes the incoming list (from STDIN) and processes some command on it.
  • perl -p -i.bak -e 's|/home/hosting/webs/client/domain/web|/var/www/domain/web/|g' -- Run perl by iterating over all the file names passed in (-p), overwriting it after making a backup (-i.bak means modify file in place, after creating a backup file with .bak suffix) and running the search and replace regex on the contents of the file (-e means "run the following as a one liner program).

The result was a very rapid replacement of all the path problems.


Tags: perl, xargs
Last update:
2014-05-02 07:38
Average rating:0 (0 Votes)

You can comment this FAQ

Chuck Norris has counted to infinity. Twice.

Records in this category