Re: New Line at End File
by tachyon (Chancellor) on Dec 09, 2002 at 23:29 UTC
|
[tachyon@www cgi-bin]# cat ./test.pl
#!/usr/bin/perl
my $file = '/tmp/test.txt';
open FILE, ">$file" or die $!;
print FILE "foo\nbar\nfoo\nbar\nfoo\nbar\nfoo\nbar\nfoo\nbar\nfoo\nbar
+\n\n\r\n\n\r";
close FILE;
# grab the last 20 bytes for analysis
open FILE, $file or die $!;
{
local $/ = undef;
seek FILE, -20, 2;
$EOF = <FILE>;
}
close FILE;
my $file_length = -s $file;
(my $newlines) = $EOF =~ m/([\015\012]+)\z/;
my $num_newlines = length $newlines;
print "File length $file_length bytes, number of newlines $num_newline
+s\n";
truncate $file, ($file_length - $num_newlines) or die $!;
print "Now file is ", -s $file, "bytes\n\n";
[tachyon@www cgi-bin]# ./test.pl
File length 53 bytes, number of newlines 6
Now file is 47 bytes
[tachyon@www cgi-bin]#
cheers
tachyon
s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print
| [reply] [d/l] |
|
You should have pointed out that this solution will only work if there are 20 or less newlines at the end of the file.
--
John.
| [reply] |
|
but that would have left nothing left to say.... I would generally read in 512 bytes anyway as this is a generally a sector and realistically the smallest chunk of a disk that the OS ever reads. This was an example and the limitation is self evident I would have thought. As it happens it will only take of the last 10 'newline' CRLF line endings on Windows if we want to get really picky ;-)
If you want to move on to the more arcane and esoteric neither seek() nor read() for that matter can be relied upon to do exactly what you ask. From the docs....
If you want to position file for sysread or syswrite, don't use seek--
+buffering makes its effect on the file's system position unpredictabl
+e and non-portable. Use sysseek instead.
cheers
tachyon
s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print
| [reply] [d/l] |
Re: New Line at End File
by sauoq (Abbot) on Dec 09, 2002 at 23:43 UTC
|
#!/usr/bin/perl
use strict;
use Fcntl qw(SEEK_END SEEK_CUR);
my $f = shift;
open F, "+<", $f or die "Couldn't open $f: $!\n";
seek F, -1, SEEK_END;
seek F, -2, SEEK_CUR while (getc(F) eq "\n");
truncate F, tell F;
-sauoq
"My two cents aren't worth a dime.";
| [reply] [d/l] |
|
It's nit time:^) The only question is the nit the code or me but...
Doesn't the use of -2, make this non-portable? Wouldn't this only work on DOSish systems? How about -length "\n" instead of -2?
Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.
| [reply] [d/l] |
|
-sauoq
"My two cents aren't worth a dime.";
| [reply] |
|
my $pos = tell F;
truncate F, 1 +$pos if $pos > 1;
--
John.
| [reply] [d/l] |
|
This also strips the last newline from the file.
Of course it does. That's exactly what was asked for. The OP read, "Is there an easy way to determine if there are new line characters at the bottom of a file, and if so delete them?" He didn't ask how to delete all but one newline or how to remove blank lines.
-sauoq
"My two cents aren't worth a dime.";
| [reply] |
|
Re: New Line at End File
by jdporter (Paladin) on Dec 09, 2002 at 22:41 UTC
|
Well, if the file is not too large to fit in memory ---
{
local @ARGV = $file_name;
local $^I = ''; # edit file in place (UPDATED)
local $/; # sluurp
local $_ = <>;
while ( chomp ) { }
print;
}
jdporter ...porque es dificil estar guapo y blanco. | [reply] [d/l] |
|
You could also use File::ReadBackwards to read in just the last line and test for the newline characters.
use File::ReadBackwards;
$bw = File::ReadBackwards->new('file') or die "can't read 'file' $!";
$lastline = $bw->readline;
bW | [reply] [d/l] |
|
The special variable $^I not only turns in-place editing on, it also specifies the extension for a backup of the original file. Something like $^I = '.bak' might be better than setting it to '1'. If you really don't want the backup you can set it to an empty string; in-place editing is on unless the variable is undefined.
-sauoq
"My two cents aren't worth a dime.";
| [reply] [d/l] [select] |
|
Thanks,
I think I see whats going on, but if you wouldn't mind, can you explain how this works.
Thanks
| [reply] |
|
| [reply] [d/l] [select] |
|
|
|
|
| [reply] |
Re: New Line at End File
by jmcnamara (Monsignor) on Dec 10, 2002 at 08:59 UTC
|
| [reply] [d/l] |