【问题标题】:Validate perl input - filter out inexistent files验证 perl 输入 - 过滤掉不存在的文件
【发布时间】:2012-11-04 01:52:02
【问题描述】:

我有一个 perl 脚本,我从批处理或有时从命令提示符提供输入(文本文件)。当我从批处理文件提供输入时,有时该文件可能不存在。我想捕获 No such file exists 错误并在引发此错误时执行一些其他任务。请找到下面的示例代码。

while(<>) //here it throws an error when file doesn't exists.
{
    #parse the file.
}
#if error is thrown i want to handle that error and do some other task.

【问题讨论】:

    标签: perl file validation parsing input


    【解决方案1】:

    钻石运算符 &lt;&gt; 表示:

    查看@ARGV 中的名称并将它们视为您要打开的文件。 只需遍历所有这些,就好像它们是一个大文件一样。 实际上,Perl 为此目的使用 ARGV 文件句柄

    如果没有给出命令行参数,请改用STDIN

    所以如果一个文件不存在,Perl 会给你一个错误消息 (Can't open nonexistant_file: ...) 并继续处理下一个文件。这是你通常想要的。如果不是这种情况,请手动执行。盗自perlop page

    unshift(@ARGV, '-') unless @ARGV;
      FILE: while ($ARGV = shift) {
        open(ARGV, $ARGV);
        LINE: while (<ARGV>) {
          ...         # code for each line
        }
      }
    

    遇到问题时,open function 返回一个错误值。所以总是调用openlike

    open my $filehandle "<", $filename or die "Can't open $filename: $!";
    

    $! 包含失败的原因。除了dieing,我们还可以做一些其他的错误恢复:

    use feature qw(say);
    @ARGV or @ARGV = "-"; # the - symbolizes STDIN
    FILE: while (my $filename = shift @ARGV) {
        my $filehandle;
        unless (open $filehandle, "<", $filename) {
           say qq(Oh dear, I can't open "$filename". What do you wan't me to do?);
           my $tries = 5;
           do {
             say qq(Type "q" to quit, or "n" for the next file);
             my $response = <STDIN>;
             exit      if $response =~ /^q/i;
             next FILE if $response =~ /^n/i;
             say "I have no idea what that meant.";
           } while --$tries;
           say "I give up" and exit!!1;
        }
        LINE: while (my $line = <$filehandle>) {
           # do something with $line
        }
    }
    

    【讨论】:

      【解决方案2】:

      在使用&lt;&gt;之前过滤@ARGV

      @ARGV = grep {-e $_} @ARGV;
      if(scalar(@ARGV)==0) die('no files');
      # now carry on, if we've got here there is something to do with files that exist
      while(<>) {
        #...
      }
      

      &lt;&gt; 从@ARGV 中列出的文件中读取,所以如果我们在它到达那里之前对其进行过滤,它就不会尝试读取不存在的文件。我添加了对@ARGV 大小的检查,因为如果您提供一个全部不存在的列表文件,它将在标准输入上等待(使用 的另一面)。这假设您不想这样做。

      但是,如果您不想从标准输入读取,&lt;&gt; 可能是一个糟糕的选择;您不妨逐步浏览@ARGV 中的文件列表。如果您确实想要从标准输入读取的选项,那么您需要知道您处于哪种模式:

      $have_files = scalar(@ARGV);
      @ARGV = grep {-e $_} @ARGV;
      if($have_files && scalar(grep {defined $_} @ARGV)==0) die('no files');
      # now carry on, if we've got here there is something to do;
      #   have files that exist or expecting stdin
      while(<>) {
        #...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-09
        • 2020-09-25
        相关资源
        最近更新 更多