我将总行数作为用户输入,然后我将从文件中删除那些数量的l ine。
我看到了这个learn.perl.org/faq/perlfaq5.html#How-do-I-count-the-number-of-lines-in-a-file-然后我厌倦了以下简单的逻辑。 / p>
逻辑:
这是我的代码:
#!/usr/bin/perl -w
use strict;
open IN, "<", "Delete_line.txt"
or die " Can not open the file $!";
open OUT, ">", "Update_delete_line.txt"
or die "Can not write in the file $!";
my ($total_line, $line, $number, $printed_line);
print"Enter the number of line to be delete\n";
$number = <STDIN>;
while ($line = <IN>) {
$total_line = $.; # Total number of line in the file
}
$printed_line = $total_line - $number;
while ($line = <IN>) {
print OUT $line unless $.== $printed_line;
}
好吧,我既没有在代码中出现任何错误,也没有任何输出错误?为什么我只是不知道。
任何人都可以给我一些建议。
答案 0 :(得分:12)
对大文件有效的Perl解决方案需要使用File::ReadBackwards
use File::ReadBackwards qw( );
my $num_lines = 10;
my $qfn = 'file.txt';
my $pos = do {
my $fh = File::ReadBackwards->new($qfn)
or die $!;
$fh->readline() for 1..$num_lines;
$fh->tell()
};
truncate($qfn, $pos)
or die $!;
答案 1 :(得分:6)
另一种方法是使用Tie::File
#!/usr/bin/env perl
use strict;
use warnings;
use Tie::File;
tie my @lines, 'Tie::File', 'myfile' or die "$!\n";
$#lines -= 10;
untie @lines;
这样做的好处是不将文件加载到内存中,就像它一样。
答案 2 :(得分:4)
这是一个通过流并打印除 n 之前的所有 n 行以外的所有行的解决方案: n 是命令行参数:
#!/usr/bin/perl
my @cache;
my $n = shift @ARGV;
while(<>) {
push @cache, $_;
print shift @cache if @cache > $n;
}
或单行版本:
perl -ne'BEGIN{$n=shift@ARGV}push@c,$_;print shift@c if@c>$n' NUMBER
答案 3 :(得分:2)
完成从IN读取后,您必须重新打开它或seek IN, 0, 0
重置其位置。您还必须再次将$.
设置为零。
此外,最终条件应更改为unless $. > $printed_line
,以便跳过超过阈值的所有行。
答案 4 :(得分:1)
只需反向读取文件并删除前n行: -
open my $filehandle, "<", "info.txt";
my @file = <$filehandle>;
splice(@file, -10);
print @file;
注意:这会将整个文件加载到内存中。
答案 5 :(得分:1)
“更有趣”的答案:使用Tie::File
!
use strict;
use warnings;
use Tie::File;
tie my @file, 'Tie::File', 'filename' or die "$!";
$#file -= 10;
答案 6 :(得分:1)
您可以缓冲最后10行,然后不打印剩下的10行。
use English qw<$INPLACE_EDIT>;
{ local @ARGV = $name_of_file_to_edit;
local $INPLACE_EDIT = '.bak';
my @buffer;
for ( 1..$num_lines_to_trim ) {
push @buffer, <>;
}
while ( <> ) {
print shift @buffer;
push @buffer, $_;
}
}
您也可以使用File::Slurp::edit_file_lines
执行此操作:
my @buffer;
my $limit_reached = 0;
edit_file_lines {
push @buffer, $_;
return ( $limit_reached ||= @buffer > $num_lines_to_trim ) ? shift @buffer
: ''
;
} $name_of_file;
答案 7 :(得分:0)
使用像for
#!/usr/bin/perl -w
use strict;
open(my $in,"<","Delete_line.txt") or die "Can not open the file $!";
open(my $out,">","Update_delete_line.txt") or die"Can not write in the file $!";
print"Enter the number of lines to be delete\n";
my $number=<STDIN>;
my @file = <$in>;
for (my $i = 0; $i < $#file - $number + 1; $i++) {
print $out $file[$i];
}
close $in;
close $out;
答案 8 :(得分:0)
my $num_lines = 10;
my $qfn = 'file.txt';
system('head', '-n', -$num_lines, '--', $qfn);
die "Error" if $?;
答案 9 :(得分:0)
#
# Reads a file trims the top and the bottom of by passed num of lines
# and return the string
# stolen from : http://stackoverflow.com/a/9330343/65706
# usage :
# my $StrCatFile = $objFileHandler->ReadFileReturnTrimmedStrAtTopBottom (
# $FileToCat , $NumOfRowsToRemoveAtTop , $NumOfRowsToRemoveAtBottom) ;
sub ReadFileReturnTrimmedStrAtTopBottom {
my $self = shift ;
my $file = shift ;
my $NumOfLinesToRemoveAtTop = shift ;
my $NumOfLinesToRemoveAtBottom = shift ;
my @cache ;
my $StrTmp = () ;
my $StrReturn = () ;
my $fh = () ;
open($fh, "<", "$file") or cluck ( "can't open file : $file for reading: $!" ) ;
my $counter = 0;
while (<$fh>) {
if ($. >= $NumOfLinesToRemoveAtTop + 1) {
$StrTmp .= $_ ;
}
}
close $fh;
my $sh = () ;
open( $sh, "<", \$StrTmp) or cluck( "can't open string : $StrTmp for reading: $!" ) ;
while(<$sh>) {
push ( @cache, $_ ) ;
$StrReturn .= shift @cache if @cache > $NumOfLinesToRemoveAtBottom;
}
close $sh ;
return $StrReturn ;
}
#eof ReadFileReturnTrimmedStrAtTopBottom
#