验证perl输入 - 过滤掉不存在的文件



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

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.

在使用<>之前过滤@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(<>) {
  #...
}

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

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

$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(<>) {
  #...
}

菱形运算符<>的意思是:

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

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

因此,如果一个文件不存在,Perl 会给你一个错误消息 ( Can't open nonexistant_file: ... ),然后继续下一个文件。这是您通常想要的。如果不是这种情况,只需手动执行即可。从perlop页面窃取:

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

open函数在遇到问题时返回 false 值。所以总是调用open喜欢

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

$!包含失败的原因。我们可以执行其他一些错误恢复,而不是die

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
    }
}

最新更新