我有幾個命令使用Perl將文本打印到文件。在這些print
命令期間,我有一個if語句,它應該刪除我正在寫入的文件的最後5行,如果該語句爲真。行,可刪除的數量始終是5如何刪除文件的最後5行
if ($exists == 0) {
print(OUTPUT ???) # this should remove the last 5 lines
}
我有幾個命令使用Perl將文本打印到文件。在這些print
命令期間,我有一個if語句,它應該刪除我正在寫入的文件的最後5行,如果該語句爲真。行,可刪除的數量始終是5如何刪除文件的最後5行
if ($exists == 0) {
print(OUTPUT ???) # this should remove the last 5 lines
}
您可以使用Tie::File:
use Tie::File;
tie my @array, 'Tie::File', filename or die $!;
if ($exists == 0) {
$#array -= 5;
}
您可以使用打印時相同的陣列,而是使用push
代替:
push @array, "line of text";
只要我讀了標題,我就認爲「Tie :: File FTW!」你擊敗了我。 +1 – 2012-02-17 14:32:19
只有我能想到的明顯方式:
前 處理所有的文件全部是相當繁瑣的,但是這是平面文件恐怕性質。
HTH
這並不是說這些「壞」建議,但Tie :: File具有內置的魔力。 – 2012-02-17 14:34:40
@Joel Berger,不是沒有。 Tie :: File從頭開始讀取文件,所以它肯定比(1)對於大文件慢得多。更不要說它會在創建文件中每一行的索引時使用的所有內存。 – ikegami 2012-02-17 21:46:49
@ikegami,你說得對#1更快(對於大文件)。所有我的意思是,Tie :: File將完成大部分工作,而不是它效率更高 – 2012-02-17 22:54:23
作爲替代,打印整個文件,除了最後5行:
open($fh, "<", $filename) or die "can't open $filename for reading: $!";
open($fh_new, ">", "$filename.new") or die "can't open $filename.new: $!";
my $index = 0; # So we can loop over the buffer
my @buffer;
my $counter = 0;
while (<$fh>) {
if ($counter++ >= 5) {
print $fh_new $buffer[$index];
}
$buffer[$index++] = $_;
$index = 0 if 5 == $index;
}
close $fh;
close $fh_new;
use File::Copy;
move("$filename.new", $filename) or die "Can not copy $filename.new to $filename: $!";
這是Richard Huxton的回答#2 – DVK 2012-02-17 14:53:07
'$ index = 0 if if 5 == $ index'也可以是寫'$ index%= 5',假設增量爲1。 – TLP 2012-02-17 15:22:38
這些是非常奇怪的公開電話。 'open'在成功時返回一個未定義的真值,在失敗時返回零 - 這兩者都不如文件句柄有用。 '$ file'是文件句柄應該在的地方,但它是未聲明的,並且你使用同一個變量兩次。 '$ filename.new'也需要雙引號或者不能編譯。 – Borodin 2012-02-17 15:25:15
File::ReadBackwards + truncate
是最快的大型文件,並且很可能以最快的速度別的了短文件。
use File::ReadBackwards qw();
my $bfh = File::ReadBackwards->new($qfn)
or die("Can't read \"$qfn\": $!\n");
$bfh->readline() or last for 1..5;
my $fh = $bfh->get_handle();
truncate($qfn, tell($fh))
or die $!;
Tie :: File是最慢的,並且使用大量的內存。避免這種解決方案。
經過測試和修復。 – ikegami 2012-02-17 22:04:10
你可以嘗試這樣的事:
open FILE, "<", 'filename';
if ($exists == 0){
@lines = <FILE>;
$newLastLine = $#lines - 5;
@print = @lines[0 .. $newLastLine];
print "@print";
}
甚至縮短:
open FILE, "<", 'filename';
@lines = <FILE>;
if ($exists == 0){
print "@lines[0 .. $#lines-5]";
}
退房這個問題:http://stackoverflow.com/questions/345513/how-can-i -delete-the-last-n-lines-of-a-file – asf107 2012-02-17 14:24:31
從堆棧溢出和官方的Perl常見問題解答:[如何更改,刪除或插入文件中的行,或追加到文件的開頭在Perl?](http://stackoverflow.com/questions/2322140/how-do-i-change-delete-or-insert-a-line-in-a-file-or-append-to-the-beginning ) – daxim 2012-02-17 14:26:06