Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Searching and replacing quoted regex strings

by Anonymous Monk
on Feb 25, 2013 at 20:01 UTC ( #1020559=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have the following code which is working, but it not exactly what I need:
#!/usr/bin/perl use File::Copy; use strict; # Set to list of files with malware present # This is produced by the following command line # grep -Rl eva1fYlbakBcVSir /var/www/html/ > /var/scripts/problem_file +s.txt # or # grep -Rl 7kyJ7kSKioDTWVWeRB3TiciL1UjcmRiLn4SKiAETs90cuZlTz5mROtHWHd +/var/www/html/ > /var/scripts/problem_files.txt my $file_list = "/var/scripts/problem_files.txt"; # Set test to 1 for test run (nothing changed, only files are listed). # Set test to 0 to actually clean the files my $test=0; #Next line works WITHOUT the php script ending at the beginning of the + malware line my $text1 = "\<\?php\ \@error_reporting\(0\)\;\ if\ \(\!isset\(\$eva1f +YlbakBcVSir\)\)\ \{\$eva1fYlbakBcVSir\ \=\ \"7kyJ"; #Next line works WITH php script ending at the beginning of the malwar +e line my $text2 = "\?\>\<\?php\ \@error_reporting\(0\)\;\ if\ \(\!isset\(\$e +va1fYlbakBcVSir\)\)\ \{\$eva1fYlbakBcVSir\ \=\ \"7kyJ"; #Next line works WITH ending </html> at the beginning of the malware l +ine my $text3 = "\<\/html\>\<\?php\ \@error_reporting\(0\)\;\ if\ \(\!isse +t\(\$eva1fYlbakBcVSir\)\)\ \{\$eva1fYlbakBcVSir\ \=\ \"7kyJ"; #Next line works WITH ending </div> at the beginning of the malware li +ne my $text4 = "\<\/div\>\<\?php\ \@error_reporting\(0\)\;\ if\ \(\!isset +\(\$eva1fYlbakBcVSir\)\)\ \{\$eva1fYlbakBcVSir\ \=\ \"7kyJ"; open (FILELIST, $file_list) or die "can't open $file_list: $!"; foreach my $file (<FILELIST>) { my $temp_file; print "Now cleaning $file\n" if (!$test); chomp $file; # get rid of line ending return open (FILE, $file) or die "can't open $file: $!"; foreach my $line (<FILE>) { if ($line =~ /^\Q$text1\E/) { print "file: $file\n" if ($test); print "malware line (test1): $line\n\n" if ($test); $line = ""; }elsif ($line =~ /^\Q$text2\E/) { print "file: $file\n" if ($test); print "malware line (test2): $line\n\n" if ($test); $line = "?>"; }elsif ($line =~ /^\Q$text3\E/) { print "file: $file\n" if ($test); print "malware line (test3): $line\n\n" if ($test); $line = "</html>"; }elsif ($line =~ /^\Q$text4\E/) { print "file: $file\n" if ($test); print "malware line (test4): $line\n\n" if ($test); $line = "</div>"; } if (!$test) { my $backup_file="$file" . "_INFECTED_COPY"; #copy("$file","$backup_file") or die "Copy failed: $!"; $temp_file="$file" . "_INFECTED_TEMP"; open (TEMPFILE,">>", $temp_file) or die "can't open $temp_ +file for writing: $!"; print TEMPFILE $line; }# end if not test }# end foreach $file close (FILE); close (TEMPFILE); rename("$temp_file", "$file") || die ( "Error renaming INFECTED_TE +MP file" ) if (!$test); }# end sub each file close (FILELIST);
As you can see, I am using the grep command to locate files that have a certain string of characters in them. Then, I am opening that list of files within this script and searching for the specific string that I wish to remove. However, I have found that the string something exists on a line starting with other text. At first, I thought I could run through each option within an if/else but I am finding too many options.

So what I need, (sudo code) is something like a regex that says (ignore what the lines starts with but replace any text that is between \<\?php\ \@error_reporting\(0\)\;\ if\ \(\!isset\(\$eva1fYlbakBcVSir\)\)\ \{\$eva1fYlbakBcVSir\ \=\ \"7kyJ
and more exact text to be defined until it gets to abc123 which is the end of the text to be replaced. Then leave anything that comes after that as well. I could probably handle this on my own if it were not for the fact that I am having to quote everything to get it to work. That has made it extremely difficult for me. Any help would be appreciated.

Thank you.

Comment on Searching and replacing quoted regex strings
Download Code
Re: Searching and replacing quoted regex strings
by vinoth.ree (Parson) on Feb 26, 2013 at 04:58 UTC

    As you are using the grep command to find the string from the file, why do not you use the grep's exact word matching option?

    grep -RlFx 7kyJ7kSKioDTWVWeRB3TiciL1UjcmRiLn4SKiAETs90cuZlTz5mROtHWHd /var/www/html/ > /var/scripts/problem_files.txt

    From the grep man page:

    -F, --fixed-strings Interpret PATTERN as a (list of) fixed strings

    -x, --line-regexp Select only those matches that exactly match the whole line.

Re: Searching and replacing quoted regex strings
by tmharish (Friar) on Feb 26, 2013 at 06:33 UTC
    I could probably handle this on my own if it were not for the fact that I am having to quote everything to get it to work. That has made it extremely difficult for me.

    See q and qq option for quoting

Re: Searching and replacing quoted regex strings
by Athanasius (Monsignor) on Feb 26, 2013 at 06:56 UTC

    Just a note on the use of backshashes in Perl strings. Consider the following, which uses 3 ways to represent the string with which $text1 is initialised:

    #! perl use strict; use warnings; my %patterns = ( original_text => "\<\?php\ \@error_reporting\(0\)\;\ if\ \(\!isset +\(\$eva1fYlbakBcVSir\)\)\ \{\$eva1fYlbakBcVSir\ \=\ \"7kyJ", double_quoted => "<?php \@error_reporting(0); if (!isset(\$eva1fYl +bakBcVSir)) {\$eva1fYlbakBcVSir = \"7kyJ", single_quoted => '<?php @error_reporting(0); if (!isset($eva1fYlba +kBcVSir)) {$eva1fYlbakBcVSir = "7kyJ', ); for (qw[original_text double_quoted single_quoted]) { my $text = $patterns{$_}; my $re = qr[^\Q$text\E]; print "\n", $_, ': ', "\n", $text, " -->\n", $re, "\n"; }

    The output shows that the strings are identical, as are the corresponding regular expressions. See Quote and Quote like Operators, which says:

    Apart from the behavior described above, Perl does not expand multiple levels of interpolation. In particular, contrary to the expectations of shell programmers, back-quotes do NOT interpolate within double quotes, nor do single quotes impede evaluation of variables when used within double quotes.

    All of this may or may not help with the stated problem. But it will certainly help in writing clearer and more readable code.

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1020559]
Approved by vinoth.ree
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (3)
As of 2014-07-31 02:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (244 votes), past polls