in reply to modify file in place in script? Regex for changing includes from SSI to PHP

Using Perl to create PHP. I love it! :)

It's not that you're "not doing that part right".
It's simply that you're "not doing that part".
You never write out your changes.

while ( my $html_file = $rule->match ) { # Change file in-place. local @ARGV = $html_file; local $^I = '.bak'; # Or '' to avoid making backups. while (<>) { ... # Keep (possibly edited) line print; } }

If you want something less magical,

while ( my $html_file = $rule->match ) { rename($html_file, "$html_file.bak") or die; open(my $fh_in, '<', "$html_file.bak") or die; open(my $fh_out, '>', $html_file) or die; while (<$fh_in>) { ... # Keep (possibly edited) line print $fh_in $_; } }

Replies are listed 'Best First'.
Re^2: modify file in place in script? Regex for changing includes from SSI to PHP
by hmbscully (Scribe) on Oct 26, 2007 at 19:23 UTC
    Let me see how much I misunderstand the "less magical" code:

    rename($html_file, "$html_file.bak")    or die;
    Makes a copy of the file with the .bak extension

    open(my $fh_in,  '<', "$html_file.bak") or die;
    Opens the copy of the file for reading

    open(my $fh_out, '>', $html_file) or die;
    Opens the original file for writing, wiping out the contents?

        while (<$fh_in>) {
    while there are file contents in the backup file, do something with them

    # Keep (possibly edited) line print $fh_in $_; }

    Print whatever the backup file is back into the backup file?

    Ok, yeah, I still don't get this. I know I should, I've read enough examples, but I don't.
    I read it as making a copy of the file I want to change, wiping out the contents of the original, modifying the copied file somehow and writing the modified text back into the copied file? Why am I not seeing this still?

    Also, I don't get the while(<$fh_in>) { s/// } instead of using

    my @lines = <$fh_in>; for (@lines) { s/// }
    because do I want to do the s/// on the entire file at once? Don't I want to go line by line?

    As for the using Perl to write PHP, as ignorant as I may seem about Perl, I am continuously frustrated with moving into PHP. What I find is that the things that PHP does easier than Perl does not outweight the things that I could do easily in Perl that cannot do easily in PHP.


    I learn more and more about less and less until eventually I know everything about nothing.
      • rename renames, not copies.

      • Oops! My error. I did
        print $fh_in $_;
        where I meant to do
        print $fh_out $_;

      • Both
        my @lines = <$fh_in>; for (@lines) { s/// }
        and
        while(<$fh_in>) { s/// }
        work a line at a time. The only difference is that the top version needlessly keeps the entire file in memory.

        Entire file at once would be

        my $text; { local $/; $text = <$fh_in>; } $text =~ s///g;
      Ok, I studied the code some more and tested and tried and realized the < and > were reversed. This is what I've got now and it seems to work and I think I get it:

      while ( my $html_file = $rule->match ) { rename($html_file, "$html_file.bak") or die; open(my $fh_in, '<', "$html_file.bak") or die; open(my $fh_out, '>', $html_file) or die; while (<$fh_in>) { my @lines = <$fh_in>; for (@lines) { #replace <!--#include virtual="[document path]"--> #with <?php include($_SERVER['DOCUMENT_ROOT'].'[document p +ath]'); ?> if (s/<!--#include virtual="(.*)"-->/<?php include(\$\ +_SERVER['DOCUMENT_ROOT'].'$1');?>/){ my $result = $1; #print the file changed and the document path for the + included file print OUTFILE "$html_file: $result\n"; } print $fh_out $_; } close($fh_in); close($fh_out); }

      I learn more and more about less and less until eventually I know everything about nothing.