Script to find & replace a multiple lines string across multiple php files and subdirectories


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Script to find & replace a multiple lines string across multiple php files and subdirectories
# 1  
Old 03-03-2012
Script to find & replace a multiple lines string across multiple php files and subdirectories

Hey guys. I know pratically 0 about Linux, so could anyone please give me instructions on how to accomplish this ?

The distro is RedHat 4.1.2 and i need to find and replace a multiple lines string in several php files across subdirectories.

So lets say im at root/dir1/dir2/ , when i execute the script it should search and replace a piece of code on php files inside this directory and its subdirectories.

The closest i found i think it was this:

Code:
Paste this into a file ‘renall’ and make it executable (chmod u+x renall): #!/bin/sh
 if [ $# -lt 3 ] ; then
   echo -e “Wrong number of parameters.”
   echo -e “Usage:”
   echo -e ”  renall ‘filepat’ findstring replacestring\n”
   exit 1
fi
 #echo $1 $2 $3
for i in `find . -name “$1″ -exec grep -l “$2″ {} \;`
do
mv “$i” “$i.sedsave”
sed “s/$2/$3/g” “$i.sedsave” > “$i”
echo $i
#rm “$i.sedsave”
done

But the string i need to find and replace have multiple lines, so i dont know how to put it in this script.

Also i dont know how to save and execute this script Smilie

EDIT: AH and by the way, i need to only DELETE the piece of code from these PHP files, i dont need to replace it with something else...

Could anyone please give me detailed instructions on this ?

Thanks in advance!

Last edited by spfc_dmt; 03-03-2012 at 10:13 AM..
# 2  
Old 03-03-2012
For starters, I'd rewrite the script you posted. The grep isn't needed, and since you're looking for a fixed set of files (*.php I assume), and fixed replace criteria, you don't need to worry about command line parameters. (You should if this is more than a one-off script, but I'll assume you don't need a script that you can run with different criteria.)

The basic script:
Code:
#!/usr/bin/env ksh

cd /directory/path/where/you/want/to/start
find . -name "*.php" | while read file
do
    echo "munging: $file"             # nice to see progress as it works
    mv "$file" "$file-"      # back it up

    ### insert sed or awk here ####  the sed in next line is for illustration only 
    sed 's/nosuchstringinthefile/noscuhreplacement/' "$file-" >"$file"
    if (( $? > 0 ))            # handle failure by putting the file back in place
    then
        echo "edit of $file failed" >&2
        mv "$file-" "$file"             # restore original
    else
        rm "$file-"               # worked, delete backup 
    fi
done



The tricky question is what criteria you need to determine which lines of the files to delete. Depending on what it is, the 'insert sed here' line in the previous script will need to change to do the right thing.

If your block of code is bounded by a unique string or phrase in the first and last lines then it will be a simple sed. The more complicated the criteria, the more complicated the code will need to be. Bottom line: post your criteria for deletion and someone will give you some help with writing a sed/awk or something that will delete things.


As for creating a script...
Start your favorite text editor, insert the code from above, or other of your choice, and save the file. Then at the command line, enter this command (assumes the file you saved was called delete_frm_php.ksh):

Code:
chmod 755 delete_frm_php.ksh

You then can invoke your script from the command line by typing delete_frm_php.ksh
# 3  
Old 03-03-2012
Hi, first thanks a lot for the help agama, appreciate it!

The php code i want to remove is a sequence of lines, it is not spread accross random lines. Its a piece of code that have around 25 lines.

Example (thats not the actual code i want to remove, just something similar):

Code:
  <?php
  $sql = "SELECT * FROM articles WHERE id = '".$_GET['article']."'";
  $do->doQuery($sql);
  $article = $do->getRows();
  if(isset($_POST['add'])) {
    if(trim($_POST['nick']) != '') {
      $nick = trim($_POST['nick']);
    } else {
      $errorX['nick'] = 'Please enter your nickname.';
    }
    if(trim($_POST['comment']) != '') {
      $comment = trim($_POST['comment']);
    } else {
      $errorX['comment'] = 'Please enter a comment.';
    }
    if(empty($errorX)) {
      $sql = "INSERT INTO comments (website, article_id, nickname, message, email) VALUES ('".$_POST['website']."','".$_GET['article']."','".$nick."','".$comment."','".$email."')";
      $do->doQuery($sql);
      header('Location: '.$_SERVER['HTTP_REFERER']);
    }
  }
  ?>

Like i said, i just need to find and remove all this code from multiple php files, i dont need to replace with anything...

So how do i put this php code in the above script ?

Thanks!

Last edited by spfc_dmt; 03-03-2012 at 03:19 PM..
# 4  
Old 03-03-2012
Is the block of code the only block that starts <?php and finishes ?>? I suspect that maybe there are other blocks that start and end this way, but on the off chance that this will be the only block like this, then this sed should work:

Code:
sed '/<?php/,/?>/d'  "$file-" >"$file"

It deletes all lines between the starting line with "<?php" and the ending "?>" line as it reads the file. The updated file is written to $file.

If you can use this sed, just replace it in the earlier example.

If there are more than one php blocks of code, then you'll need to find a unique string inside the block that you want to delete. Change the one line in the script below that has "/enter your nickname/" to contain the unique string from the block of code and it should find and delete the lines containing the string.

Code:
#!/usr/bin/env ksh

cd /directory/path/where/you/want/to/start
find . -name "*.php" | while read file
do
    echo "munging: $file"             # nice to see progress as it works
    mv "$file" "$file-"      # back it up
    awk '     # read the file and delete the block of php code
    /<?php/ { drop = idx = 0; snarf = 1; }  # start of a block; start buffering

    /?>/ {                  # end of a block
        if( ! drop )        # magic string not found -- show this block
        {
            for( i = 0; i < idx; i++ )
                printf( "%s\n", buffer[i] );
            printf( "%s\n", $0 );
        }

        snarf = 0;          # turn off buffering
        next;
    }

    ### change the string between the slants to be something unique to the block you wish to delete. 
    /enter your nickname/ { drop = 1; }    # magic string found, drop if we are in a php block

    snarf {                 # if buffering, hold the record until end of block reached.
        buffer[idx++] = $0;
        next;
    }

    { print; }              # not buffering, just print the record.
    '  "$file-" >"$file"
    if (( $? > 0 ))            # handle failure by putting the file back in place
    then
        echo "edit of $file failed" >&2
        mv "$file-" "$file"             # restore original
    else
        rm "$file-"               # worked, delete backup 
    fi
done



Hope this helps get you going.

Last edited by agama; 03-04-2012 at 01:44 PM.. Reason: corrected comment that introduced a bug
# 5  
Old 03-04-2012
Hi. When i execute the script it keeps saying:

No such file or directory cd: /directory/path/where/you/want/to/start (i did replaced this with the full path of the directory i wanted it to start)

BTW, when i execute it just by typing
Code:
delete_frm_php.ksh

it says :
Code:
-bash Command not found: delete_frm_php.ksh: Command not found

when i execute it typing
Code:
bash delete_frm_php.ksh

it says:

Code:
: command not found line 2:
: No such file or directory cd: /directory/path/where/you/want/to/start
delete_frm_php.ksh: line 32: unexpected EOF while looking for matching `''
delete_frm_php.ksh: line 41: syntax error: unexpected end of file

I also a few tweaks in the path, no success

Any clues ? Thank you!

Last edited by spfc_dmt; 03-04-2012 at 11:29 AM..
# 6  
Old 03-04-2012
Quote:
Originally Posted by spfc_dmt
Hi. When i execute the script it keeps saying:

No such file or directory cd: /directory/path/where/you/want/to/start (i did replaced this with the full path of the directory i wanted it to start)
If you cut and paste the cd command with your path at the command line do you get the same error? Screams typo in the path to me, but it is hard to say from here.

Quote:
BTW, when i execute it just by typing
Code:
delete_frm_php.ksh

it says :
Code:
-bash Command not found: delete_frm_php.ksh: Command not found

You'll need to make the script executable. You can change the file's mode to turn on the executable bit with the chmod command. This should work:
Code:
chmod 755 delete_frm_php.ksh

If you've done that then I'm a bit confused. And if you want bash to execute the script, rather than ksh, then change the ksh reference in the first line to bash.

Quote:
when i execute it typing
Code:
bash delete_frm_php.ksh

it says:

Code:
: command not found line 2:
: No such file or directory cd: /directory/path/where/you/want/to/start
delete_frm_php.ksh: line 32: unexpected EOF while looking for matching `''
delete_frm_php.ksh: line 41: syntax error: unexpected end of file

I also a few tweaks in the path, no success

Any clues ? Thank you!
Without seeing the changes you've made this is impossible to give any suggestions for. Sounds like you've got a missing quote (check out line 32 to start with). You can post the whole script if you cannot find the missing quote.
# 7  
Old 03-04-2012
Here it is:

Code:
#!/usr/bin/env ksh

cd /home/username/public_html/tests/
find . -name "*.php" | while read file
do
    echo "munging: $file"             # nice to see progress as it works
    mv "$file" "$file-"      # back it up
    awk '     # read the file and delete the block of php code
    /<?php/ { drop = idx = 0; snarf = 1; }  # start of a block; start buffering

    /?>/ {                  # end of a block
        if( ! drop )        # magic string not found -- show this block
        {
            for( i = 0; i < idx; i++ )
                printf( "%s\n", buffer[i] );
            printf( "%s\n", $0 );
        }

        snarf = 0;          # turn off buffering
        next;
    }

    ### change the string between the slants to be something unique to the block you wish to delete. 
    /PHP_STRING/ { drop = 1; }    # magic string found, drop if we're in a php block

    snarf {                 # if buffering, hold the record until end of block reached.
        buffer[idx++] = $0;
        next;
    }

    { print; }              # not buffering, just print the record.
    '  "$file-" >"$file"
    if (( $? > 0 ))            # handle failure by putting the file back in place
    then
        echo "edit of $file failed" >&2
        mv "$file-" "$file"             # restore original
    else
        rm "$file-"               # worked, delete backup 
    fi
done

Shouldnt the first line be:
Code:
#!/bin/ksh

?? Although i tested this and didnt worked aswel...

Last edited by spfc_dmt; 03-04-2012 at 12:52 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Replace a string with multiple lines

Hello Guys, I need to replace a string with multiple lines. For eg:- ABC,DEF,GHI,JKL,MNO,PQR,STU need to convert the above as below:- ABC,DEF, GHI1 GHI2 GHI3, JKL,MNO, PQR1 PQR2 PQR3, STU i have tried using code as:- (2 Replies)
Discussion started by: jassi10781
2 Replies

2. Shell Programming and Scripting

Search & Replace: Multiple Strings / Multiple Files

I have a list of files all over a file system e.g. /home/1/foo/bar.x /www/sites/moose/foo.txtI'm looking for strings in these files and want to replace each occurrence with a replacement string, e.g. if I find: '#@!^\&@ in any of the files I want to replace it with: 655#@11, etc. There... (2 Replies)
Discussion started by: spacegoose
2 Replies

3. Shell Programming and Scripting

replace (sed?) a string in file with multiple lines (string) from variable

Can someone tell me how I can do this? e.g: a=$(echo -e wert trewt ertert ertert ertert erttert erterte rterter tertertert ert) How do i replace the STRING with $a? I try this: sed -i 's/STRING/'"$a"'/g' filename.ext but this don' t work (2 Replies)
Discussion started by: jforce
2 Replies

4. Shell Programming and Scripting

how can i find number of lines in files & subdirectories

how can i find number of lines in files & subdirectories ? (3 Replies)
Discussion started by: pcbuilder
3 Replies

5. Shell Programming and Scripting

Single/Multiple Line with Special characters - Find & Replace in Unix Script

Hi, I am creating a script to do a find and replace single/multiple lines in a file with any number of lines. I have written a logic in a script that reads a reference file say "findrep" and populates two variables $FIND and $REPLACE print $FIND gives Hi How r $u Rahul() Note:... (0 Replies)
Discussion started by: r_sarnayak
0 Replies

6. Shell Programming and Scripting

Find & Replace string in multiple files & folders using perl

find . -type f -name "*.sql" -print|xargs perl -i -pe 's/pattern/replaced/g' this is simple logic to find and replace in multiple files & folders Hope this helps. Thanks Zaheer (0 Replies)
Discussion started by: Zaheer.mic
0 Replies

7. Shell Programming and Scripting

shell script to find and replace string in multiple files

I used the following script cd pathname for y in `ls *`; do sed "s/ABCD/DCBA/g" $y > temp; mv temp $y; done and it worked fine for finding and replacing strings with names etc. in all files of the given path. I'm trying to replace a string which consists of path (location of file) ... (11 Replies)
Discussion started by: pharos467
11 Replies

8. Shell Programming and Scripting

replace multiple lines in multiple files

i have to search a string and replace with multiple lines. example Input echo 'sample text' echo 'college days' output echo 'sample text' echo 'information on students' echo 'emp number' echo 'holidays' i have to search a word college and replace the multiple lines i have... (1 Reply)
Discussion started by: unihp1
1 Replies

9. UNIX for Dummies Questions & Answers

Find and replace a string in multiple files

I used the following script cd pathname for y in `ls *`; do sed "s/ABCD/DCBA/g" $y > temp; mv temp $y; done and it worked fine for finding and replacing strings with names etc. in all files of the given path. I'm trying to replace a string which consists of path (location of file) ... (2 Replies)
Discussion started by: pharos467
2 Replies

10. Shell Programming and Scripting

Find and Replace in multiple files (Shell script)

hi guys, Suppose you have 100 files in a folder and you want to replace all occurances of a word say "ABCD" in those files with "DCBA", how would you do it ??? jatin (13 Replies)
Discussion started by: jatins_s
13 Replies
Login or Register to Ask a Question