Replace string in existing file

Discussion in 'Perl' started by Rich, Feb 19, 2004.

  1. Rich

    Rich Guest

    I am trying to replace the word "test" in a file with the word
    "Change" without creating a new file using the following code:

    #! /usr/bin/perl -w

    open (IN, "+</path/to/file/test.html");

    while (<IN>){
    s/test/Change/;
    print IN;
    }

    close IN;

    The orignal file contains:

    test 1

    test 2

    test 3

    and my results are:

    test 1

    test 2

    test 3
    test 1
    Change 1
    test 3
    Change 3

    I am looking for the results to be:

    Change 1

    Change 2

    Change 3

    and that is what I get if I output the print to a new file or to
    <STDOUT>.

    What am I doing wrong? Any help would be much appreciated.

    Thanks in advance
    Rich, Feb 19, 2004
    #1
    1. Advertising

  2. Rich

    toylet Guest

    you need remember and reset the file pointer before writing out the
    result, right before "print IN".

    > #! /usr/bin/perl -w
    >
    > open (IN, "+</path/to/file/test.html");
    >
    > while (<IN>){
    > s/test/Change/;
    > print IN;
    > }
    >
    > close IN;


    --
    .~. Might, Courage, Vision. In Linux We Trust.
    / v \ http://www.linux-sxs.org
    /( _ )\ Linux 2.4.22-xfs
    ^ ^ 4:58pm up 2 days 18:52 load average: 1.00 1.00 1.00
    toylet, Feb 19, 2004
    #2
    1. Advertising

  3. Rich

    Joe Smith Guest

    Rich wrote:

    > I am trying to replace the word "test" in a file with the word
    > "Change" without creating a new file using the following code:
    >
    > open (IN, "+</path/to/file/test.html");
    > while (<IN>){
    > s/test/Change/;
    > print IN;
    > }
    > close IN;


    The obvious problem is that you're not using seek().

    The not so obvious problem is that you're doomed to failure if the
    file is longer than the standard I/O buffer.

    If the input is like "test 19\n", then you'll be changing eight
    character lines to ten character lines. After processing four
    lines (32 bytes), you will have written four lines (40 bytes), and
    the fifth line read will consist of nothing but overwritten bytes.

    You may have to consider reading the entire file into memory,
    performing the changes, seek to the beginning, print the data
    all at once, and truncating the file to size (if it got smaller).
    -Joe
    Joe Smith, Feb 20, 2004
    #3
  4. Rich

    Rich Guest

    (Rich) wrote in message news:<>...
    > I am trying to replace the word "test" in a file with the word
    > "Change" without creating a new file using the following code:
    >
    > #! /usr/bin/perl -w
    >
    > open (IN, "+</path/to/file/test.html");
    >
    > while (<IN>){
    > s/test/Change/;
    > print IN;
    > }
    >
    > close IN;
    >
    > The orignal file contains:
    >
    > test 1
    >
    > test 2
    >
    > test 3
    >
    > and my results are:
    >
    > test 1
    >
    > test 2
    >
    > test 3
    > test 1
    > Change 1
    > test 3
    > Change 3
    >
    > I am looking for the results to be:
    >
    > Change 1
    >
    > Change 2
    >
    > Change 3
    >
    > and that is what I get if I output the print to a new file or to
    > <STDOUT>.
    >
    > What am I doing wrong? Any help would be much appreciated.
    >
    > Thanks in advance



    Thank you both for the tips. I was not aware of the seek() function
    and I am currently trying to learn how to use it correctly but I think
    I'm on the right track. I will post my results.

    Thanks - Rich
    Rich, Feb 21, 2004
    #4
  5. Rich

    Rich Guest

    (Rich) wrote in message news:<>...
    > I am trying to replace the word "test" in a file with the word
    > "Change" without creating a new file using the following code:
    >
    > #! /usr/bin/perl -w
    >
    > open (IN, "+</path/to/file/test.html");
    >
    > while (<IN>){
    > s/test/Change/;
    > print IN;
    > }
    >
    > close IN;
    >
    > The orignal file contains:
    >
    > test 1
    >
    > test 2
    >
    > test 3
    >
    > and my results are:
    >
    > test 1
    >
    > test 2
    >
    > test 3
    > test 1
    > Change 1
    > test 3
    > Change 3
    >
    > I am looking for the results to be:
    >
    > Change 1
    >
    > Change 2
    >
    > Change 3
    >
    > and that is what I get if I output the print to a new file or to
    > <STDOUT>.
    >
    > What am I doing wrong? Any help would be much appreciated.
    >
    > Thanks in advance



    Got it! I had to hold the text in an array first though.

    #! /usr/bin/perl -w

    open (IN, "+</path/to/file/test.html");

    @file = <IN>;

    seek IN,0,0;

    foreach $file (@file){
    $file =~ s/test/Change/g;
    print IN $file;
    }
    close IN;
    Rich, Feb 22, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. nrm
    Replies:
    3
    Views:
    525
  2. Alun
    Replies:
    3
    Views:
    4,496
    Masudur
    Feb 18, 2008
  3. Replies:
    0
    Views:
    182
  4. Prasad S
    Replies:
    2
    Views:
    226
    Dr John Stockton
    Aug 27, 2004
  5. V S Rawat
    Replies:
    5
    Views:
    296
    Richard Cornford
    Jul 3, 2007
Loading...

Share This Page