in reply to Re^3: head truncate
in thread head truncate

Much improved.

I think exit $files_done == 0; is equivalent to exit($files_done) == 0 rather than exit ($files_done == 0) which is what you want.

Also, ... or (warn "Couldn't open $_: $!\n", next); won't work as expected. You want ... or warn("Couldn't open $_: $!\n"), next; there. That one caught me off guard. I didn't catch it till I ran it.

When I ran it (5.6.1), I also got this warning: Parentheses missing around "my" list at ./htr_a2 line 17. Line 17 is your read. Throwing parens around read's args eliminates the warning.

I fixed the error you pointed out by using eof() and reintroduced the same functionality you had. I also added a check to be sure the first argument is numeric and positive.

#!/usr/bin/perl -w use strict; use constant BLOCKSIZE => 128 * 1024; my $USAGE =<<END_OF_USAGE; Usage: $0 nbytes file [file ...] nbytes Positive integer. Number of bytes to remove. file Name(s) of file(s) to decapitate. END_OF_USAGE die $USAGE if @ARGV < 2; my $nbytes = shift @ARGV; die $USAGE unless $nbytes eq int(0+$nbytes) and $nbytes >= 0; my $completed = 0; for my $file (@ARGV) { open(my $fh, "+<", $file) or warn("Couldn't open $file: $!\n"),nex +t; if(-s $fh > $nbytes ) { seek $fh, $nbytes, 0; my $total_in = 0; while(my $bytes_in = read $fh, my $buf, BLOCKSIZE) { my $eof = eof($fh); seek $fh, $total_in, 0; print $fh $buf; $total_in += $bytes_in; last if $eof; seek $fh, $nbytes + $total_in, 0; } } truncate $fh, tell $fh; close $fh; $completed++; } exit ($completed == 0);
-sauoq
"My two cents aren't worth a dime.";

Replies are listed 'Best First'.
Re^5: head truncate
by Aristotle (Chancellor) on Sep 13, 2002 at 21:18 UTC

    Your fixes were the ones that came to mind when the issue first occured to me. However, I spent a while to come up with a different approach because I don't like that version for two reasons, detailed in Dominus' "red flag" articles.

    eof tries to read a byte from the handle, then rewinds the file. Basically, it's a kludge.

    Also, you need to set an $eof flag before copying, then check it later. Flag variables are not integral to the algorithm at hand and usually mean the implementation is not a natural way to express that algorithm.

    I updated my second post to fix the problems you mentioned. Only cosmetics this time, luckily.. :-)

    Makeshifts last the longest.

      eof tries to read a byte from the handle, then rewinds the file. Basically, it's a kludge.

      Yes, eof is a kludge. But it's also a supported language feature. Using it only required the addition of a line of code and a small change in another. Rather than figuring out how to eliminate it, I chose to spend my time adding error checking to the input. ;-)

      I do like your algorithm better though. ++

      Update: Putting your open in the unless block changes the scope of your $fh variable though. It'll be lexical to the unless block.

      -sauoq
      "My two cents aren't worth a dime.";