I do have a whole bunch of files in a directory and from every file I want to remove the first line (including carriage return). I can read the whole file into an array of strings and write all but the first element to a new file, but that looks a bit cumbersome to me are there better ways? Oh the prefered language is Perl.
views:
196answers:
6
+4
A:
use Tie::File qw();
for my $filename (glob 'some_where/some_files*') {
tie my @file, 'Tie::File', $filename or die "Could not open $filename: $!";
shift @file;
}
PS: Would you please accept some answers to your questions?
daxim
2010-06-10 17:19:57
+1 if only for your PS. :)
Charles Boyung
2010-06-10 17:41:09
Note that this still has to read and copy the whole file, but that's inherent in the problem. I don't know of any OS that provides any other way to remove data from the beginning of a file.
cjm
2010-06-10 17:42:06
Tie::File is my obvious choice because it's been explicitly written to deal with this exact problem category efficiently.
daxim
2010-06-10 17:48:35
+10
A:
Try this one liner
perl -pi -e '$_ = "" if ( $. == 1 );' filename
I've used it before, should be all you need.
stocherilac
2010-06-10 17:35:17
+5
A:
perl -n -i -e 'print unless $. == 1' myfile
This is similar to stocherilac's answer.
But, in any case (and in all the others answer given!) you are always reading the full file. No way of avoiding that, AFAIK.
leonbloy
2010-06-10 17:41:32
+8
A:
Oh the prefered language is Perl.
Sometimes sed
is a better sed
than even perl:
sed -i 1d *
pilcrow
2010-06-10 19:26:24
A:
As pointed out by Schwern, the following does not perform an early exit as I had originally thought it would:
perl -pi -e '$_ = q// and last if $. == 1;' myFile
Seems like one cannot avoid processing the whole file after all.
Zaid
2010-06-10 20:54:35
This doesn't do what you think it does. If it did, it would violate how files work on Unix. What's really happening is `$_ = ""` is always false so `$_ = "" and last` is the same as `0 and last`. It short circuits and never calls `last`. You have written: `perl -pi e '$_ = q// if $. == 1' myFile` which is a clever way to not print the first line, but it most definitely reads the whole file. Run with with `-MO=Deparse` to get the code and run it in the debugger to see. `do { this; that; } if something` is a safer construct.
Schwern
2010-06-10 22:24:54
@Schwern : My bad. It took a while for your explanation to sink in, but I see your point.
Zaid
2010-06-11 06:55:41