Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Perl从文件中删除一行?_Perl - Fatal编程技术网

如何使用Perl从文件中删除一行?

如何使用Perl从文件中删除一行?,perl,Perl,我正在尝试从文本文件中删除一行。相反,我已经抹掉了整个文件。有人能指出错误吗 removeReservation("john"); sub removeTime() { my $name = shift; open( FILE, "<times.txt" ); @LINES = <FILE>; close(FILE); open( FILE, ">times.txt" ); foreach $LINE (@LINES)

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

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/>");
}

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

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/>" ); 
}
#/usr/bin/env perl
严格使用;
使用警告;
移除时间(“约翰”);
子删除时间{
我的$name=shift;
打开(文件“times.txt”);
foreach my$行(@LINES){
打印文件$LINE,除非($LINE=~m/$name/);
} 
关闭(文件);
打印(“预订成功删除。
”); }
还有几件事需要注意:

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

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

奥尔德的答案是,但他应该测试开放式语句是否成功。如果文件
times.txt
不存在,您的程序将继续它的快乐之路,而不会有任何关于发生了可怕事情的警告

与oalders的计划相同,但:

  • 测试打开的
    的结果
  • 使用由三部分组成的开放式语句,这更能证明问题。如果文件名以
    |
    开头,则程序将以旧的两部分语法失败
  • 不使用全局文件句柄——特别是在子例程中。文件句柄在作用域中通常是全局的。想象一下,如果我在主程序中有一个名为
    file
    的文件句柄,并且我正在读取它,我调用了这个子程序。那会引起问题。使用本地范围的文件句柄名称
  • 变量名称应为小写。常量都是大写的。这只是一个随着时间而发展的标准。不遵循它会导致混乱
  • 由于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/>" ); 
    }
    
    #/usr/bin/env perl
    严格使用;
    使用警告;
    removeTime(“john”,“times.txt”);
    子删除时间{
    我的$name=shift;
    我的$time\u文件=班次;
    if(未定义$time\u文件){
    #确保$time\u文件也已传入。
    die qq(未传递给子程序“removeTime”的时间文件名\n);
    }
    #将文件读入数组进行处理
    打开(我的$read\u fh,“,$time\u文件)
    或死qq(无法打开文件“$time\u file”进行写入:$!\n);
    foreach my$行(@file_行){
    打印{$write_fh}$行,除非($line=~/$name/);
    } 
    关闭($write_fh);
    打印(“预订成功删除。
    ”); }
    这在中


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

    以防有人想删除文件中的所有行

    perl -ni -e 'print unless /whatever/' filename
    
    例如,文件(第4行为空;第5行有3个空格):

    要删除与图案匹配的线条,有些人可能会使用:

    #删除所有带有字符“a”的行
    perl-pi-e's/*a.*/'fileTest和&sed-i'/^$/d'fileTest;
    
    结果是:

    t e st1
      e
       
        bb bb
    cc
    
    相关的:

    perl-h
    #-p假设循环类似于-n,但打印行也类似于sed
    #-i[扩展名]就地编辑文件(如果提供扩展名,则进行备份)
    #-e程序一行程序(允许多行-e,省略程序文件)
    sed-h
    #-i[后缀],--in-place[=后缀]
    #就地编辑文件(如果提供后缀,则进行备份)
    

    @geekosaur我没有从警告中得到任何信息。那么,您的输出将转到其他地方,而不是它应该在的地方。检查你在哪里写的。@geekosaur,真正的程序可能在其他地方使用
    NEWLIST
    ,这意味着你不会得到“只使用一次”的警告。我希望出现“未打开的文件句柄上的print()”警告,但可能它是打开的,他只是没有注意到输出在该文件中。@cjm,是的,这就是后面(“不去你想去的地方”)评论的要点。
    sd'行将被删除“$”\n“文件”
    。添加
    --string模式
    以禁用正则表达式。这在风格上比我的答案要好。IIRC我刚刚更改了代码的最小数量,以使示例正常工作,但是如果您真的想清理问题,那么打开3 arg并检查打开是否成功是关键。使用autodie和/或File::Slurp确实可以减少代码,但这是一个比我自己更彻底的响应。感谢这个概念,我一直在努力在一个文件句柄中读取和更新行!或者,反过来说:
    perl-pi-e的/*随便什么.//'文件名
    @r_2是否删除了行,或者只是将其置为空?我期待后一种行为。它只会使它变成空的
    。|sed-i'/^$/d'文件路径
    以删除空行或
    。|sed-i'/^\s*$/d'文件路径
    (包括仅带空格的文件)。相关的:
    t e st1
    test2 a
      e
    
       
    aa 
        bb bb
    test3a
    cc
    
    t e st1
      e
       
        bb bb
    cc