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

Hello. From now on my screen name will be whiteperl and i'm new here. I have travelled far across cyberspace insearch of a master of perl. I will then copy him and study his every script until I become a master myself. Since this is my very first post, here is my very first question: Is there a way to edit text files without reading the entire file into an array?

-whiteperl

edited: Mon Jul 1 13:33:04 2002 by jeffa - changed title (was: Far across cyberspace)

  • Comment on Editing a text file without reading it into an array

Replies are listed 'Best First'.
Re: Far across cyberspace
by newrisedesigns (Curate) on Jun 30, 2002 at 05:44 UTC

    You could (but of course, TMTOWTDI):

    open ($in, $infile) or die("Cannot open $infile"); open ($out, '>', $outfile) or die("Cannot open $outfile"); flock($out, 2); #lock output file while(<$in>){ ### edit each line here using $_ print $out $_; ## print each line to output } close($out); close($in);

    As for monks to study, I suggest for starters looking at the posts of merlyn, tilly, jcwren, erudil, and crazyinsomniac (in no particular order).

    Every monk here has something from which you can learn, and I'm sure you will have many ideas to contribute.

    Update: followed Aristotle's suggestion and replaced foreach with while.
    I should have known this, because "while(<$fh>)" was an answer to a question I previously asked. Sorry for the confusion, I'm just foreach happy. :)

    John J Reiser
    newrisedesigns.com

      Careful. foreach expands the bracketed list first so you still slurp the file. You only sidestep the declaration of a temporary array variable. Your code will however work exactly as intended - without the need for any other modifications - if you simply substitute foreach for while.

      Makeshifts last the longest.

      As for monks to study...

      I recommend taking a stroll over to the Tutorials section. Most would probably find it serves as better introductory material than camel code ;-). Also, if you're looking for a good Perl book Learning Perl is an excellent choice.

        thanks :)
Re: Far across cyberspace
by Zaxo (Archbishop) on Jun 30, 2002 at 05:40 UTC
    perl -pi -e's/futile/effective/g' file.txt

    I'm glad cyberspace finally settled down for you

    After Compline,
    Zaxo

Re: Editing a text file without reading it into an array
by bronto (Priest) on Jul 01, 2002 at 17:11 UTC

    Welcome, brother whiteperl :-)

    Is there a way to edit text files without reading the entire file into an array?

    Well, it's a matter of context. As you will learn reading the fine documents other monks pointed you to, reading from a filehandle could be done in list context, e.g.: my @file_contents = <MYFILE>;; or in scalar context, e.g.: my $line = <MYFILE>.

    When you read from a file in list context, you get all the file as a list (i.e.: something you could assign to an array or give as argument to a function that requires a list, like print). Assigning to an array slurps all the file into the array, one line per element. OK, you already know this.

    When you read in scalar context, you get next line from the file. The concept of "next line" should be quite clear: if you open a file and immediately after you do a my $firstline = <MYFILE> ;, $firstline gets the first line. Next <MYFILE> "call" in scalar context will get the second line and so on.

    Whenever possible, it is better not to read a whole file in memory at once since it could eat a lot of memory if the file is big, and it could take a lot of time, too. Reading step by step, like while (my $line = <MYFILE>) { do_something_with($line) } is often better.

    Ciao!
    --bronto

    Update: of course, do_something_with($line) could end up in messing up $line and printing out to another filehandle, which is what I understand you call editing :-)

    # Another Perl edition of a song:
    # The End, by The Beatles
    END {
      $you->take($love) eq $you->made($love) ;
    }

Re: Editing a text file without reading it into an array
by mirod (Canon) on Jul 01, 2002 at 17:25 UTC

    You can try using Tie::File, which will try as much as possible not to read the entire file into an array, while letting you use it as an array of lines.