6

我正在尝试从文本文件中删除一行。相反,我已经清除了整个文件。有人可以指出错误吗?

removeReservation("john");

sub removeTime() {
    my $name = shift;

    open( FILE, "<times.txt" );
    @LINES = <FILE>;
    close(FILE);
    open( FILE, ">times.txt" );
    foreach $LINE (@LINES) {
        print NEWLIST $LINE unless ( $LINE =~ m/$name/ );
    }
    close(FILE);
    print("Reservation successfully removed.<br/>");
}

示例 times.txt 文件:

04/15/2012&08:00:00&bob
04/15/2012&08:00:00&john
4

5 回答 5

20
perl -ni -e 'print unless /whatever/' filename
于 2013-06-04T13:46:40.277 回答
9

Oalder 的回答是正确的,但他应该测试 open 语句是否成功。如果该文件times.txt不存在,您的程序将继续以愉快的方式继续进行,而不会发出警告说发生了可怕的事情。

与 oders' 相同的程序,但:

  1. 测试的结果open
  2. 使用三部分的开放语句,这更容易证明。如果您的文件名以>or开头|,您的程序将使用旧的两部分语法失败。
  3. 不使用全局文件句柄——尤其是在子程序中。文件句柄通常在范围内是全局的。FILE想象一下,如果我在我的主程序中命名了一个文件句柄,并且我正在阅读它,我调用了这个子例程。那会引起问题。使用本地范围的文件句柄名称。
  4. 变量名应该小写。常量都是大写的。它只是随着时间的推移而发展起来的标准。不遵守它可能会导致混乱。
  5. 由于 oalders 将程序放在子例程中,因此您也应该在子例程中传递文件名......

这是程序:

#!/usr/bin/env perl 

use strict; 
use warnings; 

removeTime( "john", "times.txt" ); 

sub removeTime { 
    my $name      = shift;
    my $time_file = shift;

    if (not defined $time_file) {
        #Make sure that the $time_file was passed in too.
        die qq(Name of Time file not passed to subroutine "removeTime"\n);
    }

    # Read file into an array for processing
    open( my $read_fh, "<", $time_file )
       or die qq(Can't open file "$time_file" for reading: $!\n); 

    my @file_lines = <$read_fh>; 
    close( $read_fh ); 

    # Rewrite file with the line removed
    open( my $write_fh, ">", $time_file )
        or die qq(Can't open file "$time_file" for writing: $!\n);

    foreach my $line ( @file_lines ) { 
        print {$write_fh} $line unless ( $line =~ /$name/ ); 
    } 
    close( $write_fh ); 

    print( "Reservation successfully removed.<br/>" ); 
}
于 2012-04-16T04:57:46.420 回答
8

看起来您正在打印到尚未定义的文件句柄。至少您还没有在示例代码中定义它。如果启用严格和警告,您将收到以下消息:

Name "main::NEWLIST" used only once: possible typo at remove.pl line 16.

print NEWLIST $LINE unless ($LINE =~ m/$name/);

此代码应该适合您:

#!/usr/bin/env perl 

use strict; 
use warnings; 

removeTime( "john" ); 

sub removeTime { 
    my $name = shift; 

    open( FILE, "<times.txt" ); 
    my @LINES = <FILE>; 
    close( FILE ); 
    open( FILE, ">times.txt" ); 
    foreach my $LINE ( @LINES ) { 
        print FILE $LINE unless ( $LINE =~ m/$name/ ); 
    } 
    close( FILE ); 
    print( "Reservation successfully removed.<br/>" ); 
}

还有几点需要注意:

1) 当您的意思是 removeTime() 时,您的示例代码调用 removeReservation()

2)除非您打算使用原型,否则您不需要在子例程定义中使用圆括号。请参阅我上面的示例。

于 2012-04-15T23:19:29.963 回答
4

这是在常见问题解答中。

如何在文件中更改、删除或插入一行,或附加到文件的开头?

总是值得检查常见问题解答。

于 2012-04-16T09:19:39.330 回答
0

以防万一有人想从文件中删除所有行。

例如,一个文件(第 4 行为空;第 5 行有 3 个空格):

t e st1
test2 a
  e

   
aa 
    bb bb
test3a
cc

要删除与某些可能使用的模式匹配的行:

# Remove all lines with a character 'a'
perl -pi -e 's/.*a.*//' fileTest && sed -i '/^$/d' fileTest;

结果:

t e st1
  e
   
    bb bb
cc

有关的:

perl -h
    # -p                assume loop like -n but print line also, like sed
    # -i[extension]     edit <> files in place (makes backup if extension supplied)
    # -e program        one line of program (several -e's allowed, omit programfile)

sed -h
    # -i[SUFFIX], --in-place[=SUFFIX]
    #                edit files in place (makes backup if SUFFIX supplied)

参考1参考2

于 2021-06-09T18:57:40.683 回答