[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl-AnyPerl] Simple Task I can't do with Perl.....



On Mon, Aug 30, 1999 at 12:43:43PM -0400, Paul Uttermohlen wrote:
> <Perl Newbie Disclaimer>
> I am fully aware of and singularly responsible for my newbie ignorance of
> Perl. Foregiveness humbly requested.
> </Perl Newbie Disclaimer>
> 
> Hi,
> 
> There is one simple thing I need to do with Perl that I have not yet been
> able to figure out. Could someone tell me how I can open a text file and
> insert a single character such as a carriage return at the beginning of the
> file?
> 

Sounds like an FAQ.

perlfaq5:

     How do I change one line in a file/delete a line in a file/insert a
     line in the middle of a file/append to the beginning of a file?

     Although humans have an easy time thinking of a text file as being a
     sequence of lines that operates much like a stack of playing cards --
     or punch cards -- computers usually see the text file as a sequence of
     bytes.  In general, there's no direct way for Perl to seek to a
     particular line of a file, insert text into a file, or remove text
     from a file.

     (There are exceptions in special circumstances.  Replacing a sequence
     of bytes with another sequence of the same length is one.  Another is
     using the $DB_RECNO array bindings as documented in the DB_File
     manpage.  Yet another is manipulating files with all lines the same
     length.)

     The general solution is to create a temporary copy of the text file
     with the changes you want, then copy that over the original.

         $old = $file;
         $new = "$file.tmp.$$";
         $bak = "$file.bak";

         open(OLD, "< $old")         or die "can't open $old: $!";
         open(NEW, "> $new")         or die "can't open $new: $!";

         # Correct typos, preserving case
         while (<OLD>) {
             s/\b(p)earl\b/${1}erl/i;
             (print NEW $_)          or die "can't write to $new: $!";
         }

         close(OLD)                  or die "can't close $old: $!";
         close(NEW)                  or die "can't close $new: $!";

         rename($old, $bak)          or die "can't rename $old to $bak: $!";
         rename($new, $old)          or die "can't rename $new to $old: $!";

     Perl can do this sort of thing for you automatically with the -i
     command-line switch or the closely-related $^I variable (see the
     perlrun manpage for more details).  Note that -i may require a suffix
     on some non-Unix systems; see the platform-specific documentation that
     came with your port.

         # Renumber a series of tests from the command line
         perl -pi -e 's/(^\s+test\s+)\d+/ $1 . ++$count /e' t/op/taint.t

         # form a script
         local($^I, @ARGV) = ('.bak', glob("*.c"));
         while (<>) {
             if ($. == 1) {
                 print "This line should appear at the top of each file\n";
             }
             s/\b(p)earl\b/${1}erl/i;        # Correct typos, preserving case
             print;
             close ARGV if eof;              # Reset $.
         }

     If you need to seek to an arbitrary line of a file that changes
     infrequently, you could build up an index of byte positions of where
     the line ends are in the file.  If the file is large, an index of
     every tenth or hundredth line end would allow you to seek and read
     fairly efficiently.  If the file is sorted, try the look.pl library
     (part of the standard perl distribution).

     In the unique case of deleting lines at the end of a file, you can use
     tell() and truncate().  The following code snippet deletes the last
     line of a file without making a copy or reading the whole file into
     memory:

             open (FH, "+< $file");
             while ( <FH> ) { $addr = tell(FH) unless eof(FH) }
             truncate(FH, $addr);

     Error checking is left as an exercise for the reader.

==== Want to unsubscribe from this list?
==== Send mail with body "unsubscribe" to macperl-anyperl-request@macperl.org