Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Search/Replace with PERL

Status
Not open for further replies.

hazeljean

Technical User
Aug 23, 2003
16
US
I am searching and replacing strings in many text files. I need to search for a sring and replace with anither string.
I have it woring fine unless my string starts and ends with brackets[]...it goes carzy. I have many strings that start and end with brackets. Any ideas?

Thanks
 
Can you paste a sample text line from one of your files along with the code you are currently using? That would be very helpful.
 
example:

[fill_in_blank] replaced with "Other"


perl command:

perl sarreg.pl [fill_in_blank] Other *.txt

perl script:

#!/usr/bin/perl

#
# DESC: Search and Replace
#

print "\nmksr Search and Replace $ver\n";

my $find = $ARGV[0];
my $replace = $ARGV[1];
my $glob = $ARGV[2];

@filelist = <*$glob>;

if ( (!$find) || (!$replace) || (!$glob) ) {
print &quot;Search and replace recursively through the current directory\n&quot;;
print &quot;replacing <find> with <replace> in each file specified.\n&quot;;
print &quot;To use wildcards leave off the * Ex: '.txt' \n\n&quot;;
print &quot; mksr <find> <replace> <file>\n&quot;;

exit(0);
}


# process each file in file list
foreach $filename (@filelist) {
$filename1 = $filename;


# retrieve complete file
open (IN, &quot;$filename&quot;) || die(&quot;Error Reading File: $filename $!&quot;);
{
undef $/;
$infile = <IN>;
}
close (IN) || die(&quot;Error Closing File: $filename $!&quot;);
$_ = $user_data = $filename;
$OK_CHARS='A-Za-z0-9. '; # A restrictive list, which
# should be modified to match
# an appropriate RFC, for example.
s/[^$OK_CHARS]/_/go;
$user_data = $_;
$output = $replace;

$infile =~ s/$find/$output/g;
print &quot; P: $user_data\n&quot;;

# write complete file
open (PROD, &quot;>$filename&quot;) || die(&quot;Error Writing to File: $filename $!&quot;);
print PROD $infile;
close (PROD) || die(&quot;Error Closing File: $filename $!&quot;);

}

print &quot;\nFinished.\n&quot;;


exit(0);
 
It sounds like the regex is interpreting your brackets as part of the regex, so when $filename is fed into the regex it now looks like this:

Code:
s/[^[some string from your file with brackets]]/_/go;


The brackets still remain significant to the regex. To make them insignificant, you need to use the \Q quoting escape.

Code:
s/[\Q^$OK_CHARS]/_/go;

I just learned about the \Q myself while reading Oreilly's &quot;Learning Perl on Win32&quot;, so I am not sure if the \Q go inside or outside the brackets. You might have to play around with its position to obtain the desired results. It will cause your brackets to just be read as part of the string though.




 
Tried all combinations...no change.
Hope someone has a clue?

Thanks
Hj
 
I created a single file called &quot;sortedtext1.txt&quot; with the following information in it:

7=>to
7=>me
3=>hi
2=>talk
2=>big
1=>hello
[1=>today]
1=>are
1=>how
[1=>you]


I made sure that I put a few brackets in.

Then I modified the code to test. Here it is.

Code:
    open (IN, &quot;c:/sortedtest1.txt&quot;) || die(&quot;Error Reading File: $filename $!&quot;);
    {
        undef $/;
        $infile = <IN>;
    }
    close (IN) || die(&quot;Error Closing File: $filename $!&quot;);
    $_ = $user_data = $filename;
    $OK_CHARS='A-Za-z0-9. ';    # A restrictive list, which
                    # should be modified to match
                    # an appropriate RFC, for example.
    s/[^$OK_CHARS]/_/go;
    $user_data = $_;
    $output = $replace;

        $infile =~ s/$find/$output/g;
    print &quot;    P: $user_data\n&quot;;

    # write complete file 
     open (PROD, &quot;>c:/sortedtest1.txt&quot;) || die(&quot;Error Writing to File: $filename $!&quot;);
     print PROD $infile;
     close (PROD) || die(&quot;Error Closing File: $filename $!&quot;);


   print &quot;\nFinished.\n&quot;;


   exit(0);

I stripped out the file loop part of it but left the main part unchanged.  I ran the code with the following command:  test.pl = :
The results of ouput were:

7:>to
7:>me
3:>hi
2:>talk
2:>big
1:>hello
[1:>today]
1:>are
1:>how
[1:>you]

It appears that everything worked as it should despite the [], but I did get some warnings because I ran the script with -w turned on.  The warnings are:

Use of uninitialized value in substitution (s///) at C:\perlscripts\test.pl line 11.
Use of uninitialized value in concatenation (.) or string at C:\perlscripts\test.pl line 16.
    P:

Finished.


Something is funny with s/^$OK_CHARS/_/go; and the resultant $user_data = $_.  Don't know what causes these errors.  Does anybody else have an idea?
 
What did you change in code?
Looks same as mine?

Thanks
 
with your code ...replace a string enclosed with brackets by another text string
Example:
replace [fill_in_blank] with Enter Item

I am using DOS command line. bracket problem might be in command line rather than Perl script?

Thanks
 
Okay, I think I have it figured out know. I didn't catch that your were specify a string with brackets on the command line. So, I did this:

test.pl [to] to

and got this result &quot;[toto]&quot;. Sound familiar? Anyway, I moved the \Q command to

s/\Q$find/$output/g;

and ran the script again. This time, &quot;[to]&quot; was properly replaced by &quot;to&quot;.

Hope that helps!
 
Thank you!!!!
What one little letter Q can do....A Miracle!

 
I can't code perl so I must ask you all: I used to have a simple .pl file that would enable me to change a string/letter in a file, and I could use it from Windows NT/2000/XP command prompt like this:

perl repl.pl <test.txt >tested.txt

And I could change the strings in the .pl file easily (I remember they appeared in the code like this: /string/ ).
With this it would be possible to replace underscores in text with spaces etc. Could anyone help me and offer me the code for this kind of simple .pl file please?

And if you're having a hard time trying to understand what I mean please let me know.
 
easy enough

in repl.pl

while(<>){
# this does the replace, the g means do all the _'s it
# finds, without that it would just do the first one
s/_/ /g;
print;
}


Mike

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

It's like this; even samurai have teddy bears, and even teddy bears get drunk.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top