写自动化任务时,经常需要让ref="/tag/134/" style="color:#479099;font-weight:bold;">脚本灵活接收外部输入。比如你每天要处理不同的日志文件,总不能每次都改代码吧?这时候,命令行参数就派上用场了。在 Perl 脚本里,处理命令行参数其实挺简单,也不需要引入复杂模块就能搞定。
默认的 @ARGV 数组
Perl 把命令行参数自动存到一个叫 @ARGV 的数组里。你运行脚本时跟在后面的那些内容,都会按顺序放进去。
比如有这样一个脚本:
#!/usr/bin/perl
foreach my $arg (@ARGV) {
print "收到参数:$arg\n";
}
你这样运行:
perl script.pl file1.txt file2.txt --debug
输出就会是:
收到参数:file1.txt
收到参数:file2.txt
收到参数:--debug
按位置取参数
很多脚本习惯按位置读参数。比如第一个是文件名,第二个是操作模式。
#!/usr/bin/perl
my $filename = $ARGV[0];
my $mode = $ARGV[1] || 'read';
print "准备以 $mode 模式处理文件 $filename\n";
运行 perl process.pl data.csv write,就会输出:
准备以 write 模式处理文件 data.csv
用 Getopt::Long 处理选项
如果参数多了,或者想支持 --verbose、-v 这种常见格式,直接操作 @ARGV 就容易乱。这时候可以用 Getopt::Long 模块。
#!/usr/bin/perl
use Getopt::Long;
my $verbose = 0;
my $output = 'result.txt';
my @inputs;
GetOptions(
'verbose|v' => \$verbose,
'output=s' => \$output,
'input=s@' => \@inputs,
);
print "详细模式:$verbose\n";
print "输出文件:$output\n";
print "输入文件:" . join(', ', @inputs) . "\n";
运行起来像这样:
perl tool.pl --verbose --output=report.html --input=a.txt --input=b.txt
它会清晰地解析出各个选项。注意 s 表示字符串,@ 表示可重复,|v 让 --verbose 也能用 -v 替代。
实际场景:批量重命名文件
假设你想写个脚本,把某个目录下的 .log 文件改成 .txt。可以这样设计:
#!/usr/bin/perl
use Getopt::Long;
use File::Basename;
my $dir = '.';
GetOptions('dir=s' => \$dir);
opendir(my $dh, $dir) or die "无法打开目录 $dir: $!";
while (my $file = readdir($dh)) {
next unless $file =~ /.log$/;
rename("$dir/$file", "$dir/" . basename($file, '.log') . '.txt');
print "已重命名:$file -> " . basename($file, '.log') . '.txt\n';
}
closedir($dh);
运行 perl rename_logs.pl --dir=/var/log,就能自动处理指定目录里的日志文件。
命令行参数让脚本变得更实用。不管是简单传几个值,还是支持复杂的选项组合,Perl 都能轻松应对。写完一次,以后直接命令行调用,省得反复改代码。