diff options
author | brian d foy <bdfoy@cpan.org> | 2009-11-19 18:10:48 -0600 |
---|---|---|
committer | brian d foy <bdfoy@cpan.org> | 2009-11-19 18:10:48 -0600 |
commit | 589a5df2575124305cbb6773b00c1d338c9b8553 (patch) | |
tree | 441bef92d8ec76520a83fde900c4ac007a151d61 /pod/perlfaq5.pod | |
parent | e1d16ab77edac901d7fbfed3aa4b801de9f3325e (diff) | |
download | perl-589a5df2575124305cbb6773b00c1d338c9b8553.tar.gz |
* FAQ sync for Nov blead release
This comes from 028b6d17a07335707c2b234cb69ac4051ed48435 in
git@github.com:briandfoy/perlfaq.git
Diffstat (limited to 'pod/perlfaq5.pod')
-rw-r--r-- | pod/perlfaq5.pod | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/pod/perlfaq5.pod b/pod/perlfaq5.pod index d6a72c5a3c..09da5bbd06 100644 --- a/pod/perlfaq5.pod +++ b/pod/perlfaq5.pod @@ -275,6 +275,52 @@ proper text file, so this may report one fewer line than you expect. This assumes no funny games with newline translations. +=head2 How do I delete the last N lines from a file? +X<lines> X<file> + +(contributed by brian d foy) + +The easiest conceptual solution is to count the lines in the +file then start at the beginning and print the number of lines +(minus the last N) to a new file. + +Most often, the real question is how you can delete the last N +lines without making more than one pass over the file, or how to +do it with a lot of copying. The easy concept is the hard reality when +you might have millions of lines in your file. + +One trick is to use C<File::ReadBackwards>, which starts at the end of +the file. That module provides an object that wraps the real filehandle +to make it easy for you to move around the file. Once you get to the +spot you need, you can get the actual filehandle and work with it as +normal. In this case, you get the file position at the end of the last +line you want to keep and truncate the file to that point: + + use File::ReadBackwards; + + my $filename = 'test.txt'; + my $Lines_to_truncate = 2; + + my $bw = File::ReadBackwards->new( $filename ) + or die "Could not read backwards in [$filename]: $!"; + + my $lines_from_end = 0; + until( $bw->eof or $lines_from_end == $Lines_to_truncate ) + { + print "Got: ", $bw->readline; + $lines_from_end++; + } + + truncate( $filename, $bw->tell ); + +The C<File::ReadBackwards> module also has the advantage of setting +the input record separator to a regular expression. + +You can also use the C<Tie::File> module which lets you access +the lines through a tied array. You can use normal array operations +to modify your file, including setting the last index and using +C<splice>. + =head2 How can I use Perl's C<-i> option from within a program? X<-i> X<in-place> @@ -725,7 +771,7 @@ one that doesn't use the shell to do globbing. =head2 Is there a leak/bug in glob()? X<glob> -(conributed by brian d foy) +(contributed by brian d foy) Starting with Perl 5.6.0, C<glob> is implemented internally rather than relying on an external resource. As such, memory issues with @@ -913,17 +959,15 @@ Don't forget them or you'll be quite sorry. =head2 How do I get a file's timestamp in perl? X<timestamp> X<file, timestamp> -If you want to retrieve the time at which the file was last -read, written, or had its meta-data (owner, etc) changed, -you use the B<-A>, B<-M>, or B<-C> file test operations as -documented in L<perlfunc>. These retrieve the age of the -file (measured against the start-time of your program) in -days as a floating point number. Some platforms may not have -all of these times. See L<perlport> for details. To -retrieve the "raw" time in seconds since the epoch, you -would call the stat function, then use localtime(), -gmtime(), or POSIX::strftime() to convert this into -human-readable form. +If you want to retrieve the time at which the file was last read, +written, or had its meta-data (owner, etc) changed, you use the B<-A>, +B<-M>, or B<-C> file test operations as documented in L<perlfunc>. +These retrieve the age of the file (measured against the start-time of +your program) in days as a floating point number. Some platforms may +not have all of these times. See L<perlport> for details. To retrieve +the "raw" time in seconds since the epoch, you would call the stat +function, then use C<localtime()>, C<gmtime()>, or +C<POSIX::strftime()> to convert this into human-readable form. Here's an example: @@ -1124,7 +1168,7 @@ include also support for non-portable systems as well. The very first thing you should do is look into getting the Term::ReadKey extension from CPAN. As we mentioned earlier, it now even has limited support for non-portable (read: not open systems, closed, proprietary, -not POSIX, not Unix, etc) systems. +not POSIX, not Unix, etc.) systems. You should also check out the Frequently Asked Questions list in comp.unix.* for things like this: the answer is essentially the same. |