我正在写一个Perl脚本,我想要一种方法让用户输入一个文件或一个包含$ ARGV [0]中文件列表的文件。检查参数是文件名还是包含文件名列表的文件的最佳方法?
我现在这样做的方式是检查文件名是否以@开始,如果是,那么我将该文件视为文件名列表。
这绝对不是理想的做法,因为我注意到@是bash中的一个特殊字符(它是怎么做的?我只在bash中看到它在$ @中使用) 。
我正在写一个Perl脚本,我想要一种方法让用户输入一个文件或一个包含$ ARGV [0]中文件列表的文件。检查参数是文件名还是包含文件名列表的文件的最佳方法?
我现在这样做的方式是检查文件名是否以@开始,如果是,那么我将该文件视为文件名列表。
这绝对不是理想的做法,因为我注意到@是bash中的一个特殊字符(它是怎么做的?我只在bash中看到它在$ @中使用) 。
您可以在您的命令行上指定其他参数,以便对其进行不同的处理,例如,
perl script.pl file
阅读文件的内容,或
perl script.pl -l file
从文件读取文件的列表。
您可以使用getopt模块更容易地解析输入参数。
绝对是个好主意。这就是'wget'所做的,例如''wget url'或'wget -i file-containing-list-of-urls'。 –
我建议[Getopt :: Long](http://perldoc.perl.org/Getopt/Long.html)而不是[Getopt :: Std](http://perldoc.perl.org/Getopt/Std.html )。它几乎做了Getopt :: Std所做的一切,还有更多的东西(特别是很长的选项名称,如'-list file')。 –
我目前正在使用Getopt :: Long作为脚本中的其他选项。我在第一个参数中将所有的脚本写在这个环境中作为一个裸文件名,这就是为什么我需要这个功能。我想这样做我不得不选择另一个uncommon的角色,一个在选项卡完成时不会自动转义的角色。 – OregonTrail
'@'
是Perl中特殊,所以你需要逃避它在你的Perl语句 - 除非你使用非插字符串类型的'a non-interpolating $string'
或q(another non-interpolating $string)
或者你需要逃避它,像这样
if ($arg =~ /^\@/) {
...
}
插值定界符是以下任何一种:
"..."
或qq/.../
`...`
或qx/.../
/.../
或qr/.../
对于所有这些,你将不得不逃避任何文字@
。
否则,以@
开头的文件名在命令行参数中具有相当不错的优先级。
首先,你可以使用你的shell来获取列表你:因为你是对的最大命令行长度运行
perl script.pl <(cat list)
如果你不想这样做,或许,你可以使用使用前@ARGV
或ARGV
(包括<>
)如下:
@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;
请记住,你就会有意想不到的副作用,如果您有其名称以开头的文件中“@”。
'@'字符不是特殊的外壳。它只是一个特殊的参数名称,就像'?'在'$?'中为最后一个命令的退出状态。这就是为什么你会看到它被专门用作'$ @'的原因。在所有其他情况下,shell并没有给出任何意义。特别是你可以使用它作为文件名中的第一个字符。 – Jens
读取文件的第一行并检查它是否是有效的文件名? – flies