premal has asked for the wisdom of the Perl Monks concerning the following question:

I am writing a script where I want to read the strings present in one text file and search the same string in another file and replace it with other string. I am able to read the data from first file but the script is not replacing the matched string in another file. Can you please help me out with the logic. How do I achieve this? I have given my code below.

my $file1 = "C:\\temp\\file1.txt"; my $file2 = "C:\\temp\\file2.bat"; open (FILE1,"$file"); open (FILE2,"$file2"); my @file1 = <FILE1>; my @file2 = <FILE2>; close (FILE1); foreach my $search_string (@file1) { if (grep /$search_string/,@file2) { while (<FILE2>) { s/$search_string/"******"/g; print FILE2; } } } close (FILE2);
  • Comment on Read strings from a file, search and replace same string in another file.
  • Download Code

Replies are listed 'Best First'.
Re: Read strings from a file, search and replace same string in another file.
by jethro (Monsignor) on Dec 08, 2011 at 11:37 UTC

    Lets analyze your script: First it slurps the contents of FILE2 into memory which means the file pointer is at EOF (= End Of File). In the inner loop it tries to read a line from FILE2 (file pointer at EOF, so no go) and then tries to write that line directly after its original place in the same file! Also it tries to write into a file that is opened for reading.

    What seems to be missing is a line where you open FILE2 for writing (somewhere after you have read its contents). Also the inner loop has to loop over @file2, not <FILE2>

      Thanks for your reply. I did open my file for read write but dont know how it got changed while copying my code. Finally I was able to get my work done. Thanks again for your help.

Re: Read strings from a file, search and replace same string in another file.
by roboticus (Chancellor) on Dec 08, 2011 at 11:40 UTC

    premal:

    You're trying to write the results to the same file you're reading from. Instead, read from one file and write your results to a new file, like so:

    my $file1 = "C:\\temp\\file1.txt"; my $file2 = "C:\\temp\\file2.bat"; my $file3 = "C:\\temp\\file3.txt"; open (FILE1,"$file1"); open (FILE2,"$file2"); open (FILE3,">$file3"); my @file1 = <FILE1>; my @file2 = <FILE2>; close (FILE1); close (FILE2); chomp @file1; foreach (@file2) { foreach my $search_string (@file1) { s/$search_string/"******"/g; } print FILE3; } close (FILE3);

    That should solve immediate problem. Note: I haven't tested or run the updated version.

    Update: Tweaked per jethro's comments. (I really ought to not code until I finish my coffee... ;^D)

    Update 2: To avoid further embarrassment, I tested it and updated again. It passes my tests now.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      Not a good idea. In your version FILE2 is reread many times from disk even though file2 is already available in @file2. But worse, FILE3 will be written as many times as file1 has lines and only the last version will survive.

      Thanks a lot friend for helping me out. I did try various changes including this but the mistake I made was not using new file for writing the data. You guided me the correct way. Thanks again for helping me out. :)

Re: Read strings from a file, search and replace same string in another file.
by sumeetgrover (Monk) on Dec 08, 2011 at 11:32 UTC

    There are a lot of corrections needed in your code.

    • You are opening FILE2 in read mode, you should be opening in the read+write mode.

    To begin with, you need to know how to open a file in read+write mode:
    Here's the link: sysopen

    Then, you need to know how to operate upon a file in read+write mode.

    Hope the above information is useful to getting started with what you need to program.

      Thanks for your reply. I did open my file for read write but dont know how it got changed while submitting my code. Finally I was able to get my work done. Thanks again for your help.

Re: Read strings from a file, search and replace same string in another file.
by ww (Archbishop) on Dec 08, 2011 at 12:55 UTC
    premal: Note Also

    Line 4 uses $file while line 1 has that var as $file1. Had you used strict and warnings you were have known this. But maybe it's merely a transcription typo; otherwise, contrary to your statement, you could *NOT* have "read the data from first file...."

    As others noted, you should read perldoc -f open and use the three-arguement open described there.

Re: Read strings from a file, search and replace same string in another file.
by TJPride (Pilgrim) on Dec 08, 2011 at 13:16 UTC
    use strict; use warnings; my $f1 = '1.txt'; my $f2 = '2.txt'; my (@strings, $text); open (FH, $f1) || die; chomp(@strings = <FH>); open (FH, $f2) || die; $text = join '', <FH>; $text =~ s/\Q$_\E/******/g for @strings; ### Make sure it's treated as string and not expression open (FH, ">$f2") || die; print FH $text; close FH;

    1.txt:

    find search

    2.txt:

    a bunch of words with find and search and some other words

    2.txt after run:

    a bunch of words with ****** and ****** and some other words

      Hi, Thanks for your reply. I was getting stuck with error at "Died at line 9 script.pl" Line number 9 contains open (FH, $f1) || die; statement. I used another file to write the data. Thaks a lot again for your solution. :)

Re: Read strings from a file, search and replace same string in another file.
by CountZero (Bishop) on Dec 09, 2011 at 07:26 UTC
    No loops, no arrays, just an efficient regular expression applied once.
    use Modern::Perl; use Regexp::Assemble; open my $HAMLET_IN, '<', 'hamlet.txt' or die $!; my $hamlet; { local $/; # slurp mode $hamlet = <$HAMLET_IN>; } my $ra = Regexp::Assemble->new(file => 'names.txt')->re; $hamlet =~ s/$ra/*****/g; open my $HAMLET_OUT, '>', 'hamlet_new.txt' or die $!; print $HAMLET_OUT $hamlet;

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James