Michael
Michael

Reputation: 395

Script to add line with part of the pattern used to find the line

I'd like to parse all *.php files, and for each line like

$res = $DB -> query($queryVar);

I need to get:

file_put_contents('php://stderr', print_r($queryVar, TRUE));
$res = $DB -> query($queryVar);

The name of the variable $queryVar may change! I need to get it from the code!

My initial idea:

find  -not -path "*/\." -name "*.php" -type f -print0 | xargs -0 sed -i 's,SOMETHING,SOMETHING,'

but it seems to be not possible to get the name of the query variable with sed.

I also started looking at Perl: Perl: append a line after the last line that match a pattern (but incrementing part of the pattern)

But I was able to do only this:

perl -pe 's/(-> query\(.*\))/AAAAA $1 AAAAA\n$1/'  < filename.php

With 2 problems: I get the result on standard output, I need something like sed to edit the original file, as I will call it from find | xargs and anyway I get the whole found line and not only the variable:

    $res = $DB AAAAA -> query( $SQL) AAAAA
-> query( $SQL);

Upvotes: 1

Views: 87

Answers (3)

Sobrique
Sobrique

Reputation: 53508

You can use perl like sed. But really, by doing so you throw away a lot of its potential as a language. I couldn't quite tell from your question - is $queryVar a literal, or is it a variable you need to replace?

Why not try this:

#!/usr/bin/perl

use strict;
use warnings;

use File::Find;

sub process_php {
    next unless m/\.php$/;
    open( my $input, "<", $File::Find::name ) or warn $!;
    open( my $output, ">", $File::Find::name . ".new" )
        or warn $!;
    while ( my $line = <$input> ) {
        my ($query_id) = ( $line =~ m/-> query\((.*)\))/ );
        if ($query_id) {
            print {$output} "file_put_contents('php://stderr', print_r(",
                $query_id, " TRUE));\n";
        }
        print {$output} $line;
    }
    close($input);
    close($output);
}

find( \&process_php, "/path/to/php/files" );

This will:

  • search all the '*.php' files under the directory path.
  • traverse them looking for your string.
  • If it exists, add a new line just before it.
  • write a '.new' file, with the new content (Once you're happy this works, you can swap 'em over).

Upvotes: 0

Chris Smeele
Chris Smeele

Reputation: 987

You can use perl's -i flag to edit the file in place.

To only capture the query variable you need to add a capture group within the () part, as follows:

 perl -i -pe 's/^(.*-> query\((.*)\);)$/inserted_code_here($2);\n$1/' x.php

Then replace inserted_code_here with whatever you want to put on the line before the query call.

Upvotes: 1

OrenD
OrenD

Reputation: 1741

Given a file named filename.php, you can run the following command:

perl -pi -e 's/^(.+-> query\((.+?)\).*)$/file_put_contents\("php:\/\/stderr", print_r\($2, TRUE\)\);\n$1/;' filename.php

It will update the file in-place with the substitution you intended to perform.

Upvotes: 1

Related Questions