在Perl中传递命令行参数

3

我在为参数值和命令行参数分配方面遇到了麻烦。这是我实际想要做的。

Test.pl
#!/usr/bin/perl

#Variable declaration

$RUN_DIR="/home/ckhau/database/experiment/test";
    #Main program

$index=-999; 
#my $ARGV;
@files = <$RUN_DIR/b*.txt>;

foreach $file (@files)
{
 #$SCRIPT="perl abcdinfo.pl $file";
 $SCRIPT="perl abc.pl $file";
 system("$SCRIPT");       
}

我尝试用@ARGV替换b*.txt并运行程序,即当我用以下代码替换上述代码时

@files = <$RUN_DIR/@ARGV>;

然后尝试使用命令行运行。
perl Test.pl b*.txt

这给了我一个错误 perl: no match. 有人能帮我解决以下问题吗。

如何为此使用命令行参数???

我可以在命令行中使用这种语法“b*.txt”或“r_*.txt”吗???


1
这可能与shell在命令行参数中不能很好地处理*有关。 - Raghav
你在哪个shell中运行这个脚本?Windows命令提示符?Linux的bash shell? - Jonah Bishop
@Jonah Bishop:我正在使用Linux。 - unkaitha
请展示实际存在问题的代码。 - ikegami
1个回答

3

Shell试图将b*.txt扩展为当前目录中匹配文件列表。一旦您的程序接收到这些值,您的glob如下所示:

@files = </home/ckhau/database/experiment/test/b1.txt b3.txt b3.txt>

这不是你想要的,如果在 $RUN_DIR 目录中没有 b1.txt 文件,则无法找到任何文件。

为了防止 shell 全局匹配通配符文件模式,您只需要将其放入引号中,因此您的命令变成:

perl Test.pl 'b*.txt'

除此之外,您的程序真的需要改进。您应该始终在所有程序的开头使用use strictuse warnings,并在第一次使用时声明每个变量;您应该仅使用@ARGV的第一个元素作为文件模式,而不是整个数组;当您只想要它们的内容时,将标量变量放在引号中是错误的。
看看这个对原始代码的重构。
#!/usr/bin/perl

use strict;
use warnings;

my $run_dir="/home/ckhau/database/experiment/test";

my $pattern = "$run_dir/$ARGV[0]";

my $index = -999; 
my @files = glob $pattern;

foreach my $file (@files) {
  my $script = "perl abc.pl '$file'";
  system $script;
}

更新

如果你真的想要将多个通配符模式作为参数传递给Test.pl,那么你必须在每个模式前面加上$run_dir目录。最好的方法是使用File::Spec模块的rel2abs函数。完整的脚本如下:

#!/usr/bin/perl

use strict;
use warnings;

use File::Spec;

my $run_dir="/home/ckhau/database/experiment/test";

my $pattern = join ' ', map File::Spec->rel2abs($_, $run_dir), @ARGV;

my $index = -999;
my @files = glob $pattern;

foreach my $file (@files) {
  my $script = "perl abc.pl '$file'";
  system $script;
}

你在更新中提到的那个正是我想要的,即我将不得不给出许多通配符模式,但我无法安装这些 CPAN 模块,所以有没有更好的方法可以在不使用这些模块的情况下完成这个任务。 - unkaitha
建议新手使用"use strict"和"use warnings"。 - David
@unkaitha:你是说你不能在机器上安装CPAN模块,因为你没有root权限吗?如果是这样,你可以按照这些说明将模块安装到你选择的非系统Perl区域:http://linuxgazette.net/139/okopnik.html - David
@unkaitha:如果您成功建立了个人的CPAN库,请考虑使用Readonly模块。我注意到您将$RUN_DIR全部大写……如果您打算将其作为常量,则可以“使用Readonly; Readonly $RUN_DIR =>'/home/ckhau/database/experiment/test';” - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接