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

I am trying to write a code that first asks the user for a file name. If the imput name exists, the user is then asked for a word, word_1, which already exists in the given file. Then the user is asked for a second word, word_2, which is to replace word_1. Everything seems to be working fine except that word_2 is just added to the file in stead of taking the place of word_1. What am I doing wrong?

Here's the code:

#!/usr/bin/perl -w print "Please Enter the Name of a File: "; $file = <STDIN>; if (open(HANDLE, "$file")) { print "Please Enter a word from $file: "; $word_1 = <STDIN>; print "Please Enter a Word to Replace, $word_1, with: "; $word_2 = <STDIN>;} @x=<HANDLE>; open (HANDLE, "$file"); open (HANDLE, ">>$file"); foreach $variable (@x) { if ($word_1=~/$variable/i) { $variable = $word_2; print @x;}}
Thanks, Sam

Replies are listed 'Best First'.
Re: swaping words
by VSarkiss (Monsignor) on Feb 11, 2002 at 00:12 UTC

    The first problem is that your $word_1 has a newline at the end. Since this is almost surely not what you want to do, you should chomp both words after you read them in.

    As BazB has pointed out above, you're opening and closing the file several times unnecessarily. Also, if your open fails, there's not much clue about what's happening. It's much clearer to check for errors when opening, then close the handle explicitly, then open it for writing (since you'll be re-writing its contents).

    Finally, if you're going to read in the whole file and do match-and-substitute, it's a lot easier not to use an array. Just read the whole thing into a scalar, and do a global replace. Put it all together, and it looks like this:

    open HANDLE, $file or die "Couldn't open $file: $!\n"; print "Please Enter a word from $file: "; chomp($word_1 = <STDIN>); print "Please Enter a Word to Replace, $word_1, with: "; chomp($word_2 = <STDIN>); # Read the whole thing in. undef $/; $x = <HANDLE>; close HANDLE; # Re-open for writing, clobbering the file. open HANDLE, ">$file"; # Change every instance $x =~ s/$word_1/$word_2/g; # To prevent changing substrings, it would almost # certainly be better to use: # $x =~ s/\b$word_1\b/$word_2/g; # But it's your call.... print HANDLE $x;

    At this point, I should probably also chide you for not using strict and warnings, but I'll let you off easy this time. ;-)

    HTH

Re: swaping words
by BazB (Priest) on Feb 10, 2002 at 23:56 UTC

    open (HANDLE, "$file"); open (HANDLE, ">>$file");

    I'd think you only need to open the filehandle once.
    The second open() statement is opening $file for appending only, which can't be useful in this case.

    Why not use s/$word_1/$word_2/i or similar?