2011-08-24 62 views
2

我正在写一个Perl脚本,我想要一种方法让用户输入一个文件或一个包含$ ARGV [0]中文件列表的文件。检查参数是文件名还是包含文件名列表的文件的最佳方法?

我现在这样做的方式是检查文件名是否以@开始,如果是,那么我将该文件视为文件名列表。

这绝对不是理想的做法,因为我注意到@是bash中的一个特殊字符(它是怎么做的?我只在bash中看到它在$ @中使用) 。

+0

'@'字符不是特殊的外壳。它只是一个特殊的参数名称,就像'?'在'$?'中为最后一个命令的退出状态。这就是为什么你会看到它被专门用作'$ @'的原因。在所有其他情况下,shell并没有给出任何意义。特别是你可以使用它作为文件名中的第一个字符。 – Jens

+0

读取文件的第一行并检查它是否是有效的文件名? – flies

回答

5

您可以在您的命令行上指定其他参数,以便对其进行不同的处理,例如,

perl script.pl file 

阅读文件的内容,或

perl script.pl -l file 

文件读取文件的列表。

您可以使用getopt模块更容易地解析输入参数。

+2

绝对是个好主意。这就是'wget'所做的,例如''wget url'或'wget -i file-containing-list-of-urls'。 –

+4

我建议[Getopt :: Long](http://perldoc.perl.org/Getopt/Long.html)而不是[Getopt :: Std](http://perldoc.perl.org/Getopt/Std.html )。它几乎做了Getopt :: Std所做的一切,还有更多的东西(特别是很长的选项名称,如'-list file')。 –

+0

我目前正在使用Getopt :: Long作为脚本中的其他选项。我在第一个参数中将所有的脚本写在这个环境中作为一个裸文件名,这就是为什么我需要这个功能。我想这样做我不得不选择另一个uncommon的角色,一个在选项卡完成时不会自动转义的角色。 – OregonTrail

0

'@'Perl中特殊,所以你需要逃避它在你的Perl语句 - 除非你使用非插字符串类型的'a non-interpolating $string'q(another non-interpolating $string)或者你需要逃避它,像这样

if ($arg =~ /^\@/) { 
    ... 
} 

插值定界符是以下任何一种:

  • "..."qq/.../
  • `...`qx/.../
  • /.../qr/.../

对于所有这些,你将不得不逃避任何文字@

否则,以@开头的文件名在命令行参数中具有相当不错的优先级。

1

首先,你可以使用你的shell来获取列表你:因为你是对的最大命令行长度运行

perl script.pl <(cat list) 

如果你不想这样做,或许,你可以使用使用前@ARGVARGV(包括<>)如下:

@ARGV = map { 
    if (my $qfn = /^\@(.*)/s) { 
     if (!open(my $fh, '<', $qfn)) { 
      chomp(my @args = <$fh>); 
      @args 
     } else { 
      warn("Can't open $qfn: $!\n"); 
     () 
     } 
    } else { 
     $_ 
    } 
} @ARGV; 

请记住,你就会有意想不到的副作用,如果您有其名称以开头的文件中“@”。

相关问题