views:

664

answers:

4

Hopefully a nice simple one.

I've got a php3 website that I want to run on php 5.2

To start with I'd just like to have every reference to the current "index.php3" _within_each_file_ (recursively) changed to "index.php" and then move on to worrying about globals etc.

K. Go!

:)

Update: Thanks a lot! I realise that my question missed the fact that the references are in each file of a website and I wanted to do it recursively in all files/folders.

A: 

sed -i 's/php3/php/g' *

Assuming you are using a unix-like operating system.

Brian C. Lane
And one with GNU sed -- that won't work with non-GNU versions of sed.
Jonathan Leffler
Minor nitpick, @Jonathan - you'd be hard-pressed trying to find a UNIX without GNU sed nowadays.
paxdiablo
Find me a Unix-like system running PHP that doesn't have a GNU version of sed :)
Brian C. Lane
@Brian: any BSD-based machine, like FreeBSD, NetBSD, or Mac OS X.
Bill Karwin
Solaris, AIX, HP-UX, to name but three.
Jonathan Leffler
+4  A: 

How about:

for file in *.php3
do
    sed 's/\.php3/.php/g' $file > ${file%3}
done

The for/do/done loop deals with each .php3 file in turn, editing the file and replacing each string .php3 with .php, and copying the file from something.php3 to something.php.

Added for amended question:

for file in $(find . -type f -name '*.php3' -print)
do
    sed 's/\.php3/.php/g' $file > ${file%3}
done

The '-print' can usually be omitted these days, but historically, a lot of machine time was wasted by people who forgot to add it because there was originally (pre-POSIX) no default action.

This fragment is about the simplest modification of the original code to do the extended task, but isn't necessarily the best way to do it any more - it pre-generates the entire list of files before processing any. You could instead use:

find . -type f -name '*.php3' -print |
while read file
do
    sed 's/\.php3/.php/g' $file > ${file%3}
done

However, both the amended versions can run into problems if file names or path names can contain blanks or newlines or other such characters. To avoid such issues, you have to work harder - using Perl or (GNU find + xargs) or some other techniques. If you're sane, you avoid such problems. If you've inherited a less than entirely sane setup, then you may have to delve deeper into the arcana of Unix file name handling.

Jonathan Leffler
Hey Jonathan.Thanks but I need to change the php3 reference inside each file.The only file with php3 is index.php3 and that's what all the code is calling :) hence the need to change.Cheers.
gyaresu
The basic technique remains the same - tweaking the details is the main difference. If the files are already renamed, then use 'sed ... $file >tmp.$$; mv $file old.$file; mv tmp.$$ $file', for example. Or use 'perl -i.bak' and appropriate code. Or ...
Jonathan Leffler
+1  A: 

To do this recursively, use Jonathan's answer but substitute find . -type f for *.php3. Note that the back ticks are important and you can substitute any directory for "." (i.e. the current directory). Here is a version that also renames the file in the process (*.php3 -> *.php).

#!/bin/bash
for file in `find . -type f`
do
    sed 's/\.php3/\.php/g' $file > ${file//3/}
    rm $file
done
ctuffli
Hey ctuffliI made the script in the root of the webdir (a fresh copy of course) and ran it.It ate all the files in the directory except for index.php (which it renamed).Quite the odd outcome.
gyaresu
Under which OS did you try this? The script didn't eat any files on my OS X system.
ctuffli
+5  A: 
find -type f -exec perl -pi -e 's/\bindex\.php3\b/index.php/g' {} \;
Joshua Swink
Thanks Joshua! Worked perfectly.
gyaresu