我有一个perl脚本,它将目录路径作为输入,然后脚本遍历该目录中的所有文件。对于每个文件,它都会调用其他函数。
这是脚本:
#!/usr/bin/perl
use JSON;
use XML::Simple;
use File::Spec;
$num_args = $#ARGV + 1;
if ($num_args != 1) {
print "\nUsage: $0 <input directory>\n";
exit;
}
my $dir = $ARGV[0];
opendir(DIR, $dir) or die "cannot open directory";
@docs = grep(/\.xml$/,readdir(DIR));
foreach $file (@docs)
{
my $abs_path = join("",$dir,$file);
#print $abs_path;
my $return_object = some_function_call($abs_path);
print_output($return_object);
}
sub print_output
{
my $output_object = $_[0];
print $output_object;
}
我的问题是,当我正在读取输入目录时,如果不存在,怎么能使上面的脚本从“一些默认目录位置”读取。我尝试添加一些逻辑,但不适合我。这是我的第一个perl脚本,所以请原谅我,如果这个问题太基础了。
我在LINUX环境中工作。
答案 0 :(得分:5)
您犯的第一个也是最关键的错误是不使用
use strict;
use warnings;
这两个pragma提供了比你可能添加的任何其他两行代码更多的帮助。永远不要在没有它们的情况下编写Perl代码。
use JSON;
use XML::Simple;
use File::Spec;
您不使用这些模块中的任何一个,因此对于此代码,它们是多余的。
$num_args = $#ARGV + 1;
if ($num_args != 1) {
print "\nUsage: $0 <input directory>\n";
exit;
}
这可以写成
if (@ARGV != 1) {
print ...
exit;
}
因为标量上下文中的数组返回其大小。
opendir(DIR, $dir) or die "cannot open directory";
@docs = grep(/\.xml$/,readdir(DIR));
foreach $file (@docs) {
my $abs_path = join("",$dir,$file);
除非你真的需要readdir
的精确度,否则你最常想要的是glob()
。此代码将替换上面的代码:
my @docs = glob "$dir/*.xml";
它将返回相对路径(不是绝对路径,因为您的变量名称暗示 - 除非路径参数是绝对路径)。例如:examples/foo.xml
。
sub print_output {
my $output_object = $_[0];
print $output_object;
}
我认为这个子只是一个例子,因为它什么都不做,可以简化为简单的print
。
关于你要读取的默认目录的问题,对我来说这与参数的要求不一致(你检查@ARGV
)。但你可以做一个简单的存在检查:
if (not -e $dir) {
$dir = "default";
}
答案 1 :(得分:2)
constant
pragma和条件statement modifier会使您的默认逻辑更具可读性:
....
use constant DEFAULT_DIR => '/path/to/default/dir';
....
my $dir = $ARGV[0];
$dir = DEFAULT_DIR unless -e $dir;
....
(并且,是的,请注意其他人的建议:严格,警告,词汇手柄,修剪不需要的模块,避免$#array
等)。
答案 2 :(得分:1)
在opendir(DIR, $dir) or die "cannot open directory";
之前检查目录是否存在,如果没有分配$dir
变量默认值:
$default_dir = "....";
if (!-e $dir)
{
$dir = $default_dir;
}