views:

334

answers:

8

I'd like to insert

<?php include_once('google_analytics.php'); ?>

before the closing body tag of about 100 php files. Unfortunately the person who made the site didn't make a header or footer template.

What is the best way to do this? I've tried using grep/find for getting a list of files and piping the results through xargs to sed, but I've had no luck. I probably have the regex wrong. Can anyone help me out with this?

Also, are there any graphical tools for Apple OS X that you would recommend?

Thanks, Mike

edit

find . -print0 -name "*.php" | xargs -0 perl -i.bak -pe 's/<\/body>/<?php include_once("google_analytics.php"); ?>\n<\/body>/g'

works.

+1  A: 

You need to supply an array with filenames in $files to make the following solution work:

foreach ($files as $file)
{
    $txt = file_get_contents($file);

    $txt = str_replace('</body>', '<?php include_once(\'google_analytics.php\'); ?>'."\n".'</body>', $txt);

    file_put_contents($file, $txt);
}
Franz
Another smart way to do it. Thanks. I could just stick in a directory_iterator and be good to go.
mswebersd
A: 

What about a replace on

</body>

with

<?php include_once('google_analytics.php'); ?></body>

?

John at CashCommons
That's what he wants to do. He wants to know how to do it best...
Franz
Maybe what he wants to do and what he actually did are two different things?
John at CashCommons
+3  A: 

If you're interested in GUI tools, download TextMate. Put all 100 files in a folder and open that folder with TM. This will put TM in project mode, and you'll see all the files in a sidebar. Now, do Edit>Find>Find In Project, put </body> in the "find" field, <?php include_once('google_analytics.php'); ?></body> in the "replace" field, hit replace and let it run.

Ben
Downloading now! Thank you.
mswebersd
+1  A: 

Dreamweaver will do a find/replace for the entire local site; I'm sure other html editors would as well.

jeerose
Thanks... Dreamweaver is too expensive for me though.
mswebersd
A: 

Some IDE's like dreamweaver provide functionality to do find and replace in many files, entire folders etc. You can use one of those and do a find and replace replacing the close body tag with the code you want.

Vincent Ramdhanie
A: 

I'm not a PHP developer, but is PHP a valid XML format? It doesn't look like it but what do I know. Even if it is the success of this answer may depend more on whether the files you are working with are valid PHP. But...if it is it would be fairly simple to use an XML transform (xslt) to match the body tag, copy its content and append a new tag after the matched content.

Ryan Lynch
I'm not sure how XML parsers would handle <?php tags. BUT I'm 100% positive that the HTML itself wouldn't make it through an XML parser.Good suggestion though.
mswebersd
No. PHP is *not* an XML format, let alone a valid one.
Asaph
Yeah, that's what I thought. Worth a shot though.
Ryan Lynch
+2  A: 

this calls for an ed script

#!/bin/sh
for i in *.html; do
ed $i << \eof
?</body>?s/^/<?php include_once('google_analytics.php'); ?>&/
w
q
eof
done

It fires up one of the first (literally) programs ever written for Unix, Ken Thompson's ed(1) text editor on each file and makes the necessary edit. If you want it to work on specific files rather than on every .html in the directory, just change *.html to "$@".

Reading the Wikipedia link just now, I learned something interesting. Ken Thompson made the first actual application of regular expressions, apparently they were just a mathematical expression until he wrote ed(1).

DigitalRoss
Sweet, going out now, but I'll give it a go when I get back. Thank you.
mswebersd
haha, re: your edit: check out my *brilliant* description of the matter: http://stackoverflow.com/questions/1085404/what-is-regular-expression/1085469#1085469
rascher
+3  A: 

Using sed:

 sed -i s/'<\/body>'/"<?php include_once('google_analytics.php'); ?>\n<\/body>"/ *.htm

The -i option edits the file in place. If you say -iBAK then it will create a backup of the file before editing it.

rascher
Alright so all that perl nonsense was unnecessary. Good to know. :)
mswebersd