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.