我有一个包含
的Perl脚本open (FILE, '<', "$ARGV[0]") || die "Unable to open $ARGV[0]\n";
while (defined (my $line = <FILE>)) {
# do stuff
}
close FILE;
我想在目录中的所有.pp
文件上运行此脚本,所以我在Bash中编写了一个包装器脚本
#!/bin/bash
for f in /etc/puppet/nodes/*.pp; do
/etc/puppet/nodes/brackets.pl $f
done
问题
是否可以避免使用包装器脚本并让Perl脚本代替它?
答案 0 :(得分:8)
是
for f in ...;
转换为Perl
for my $f (...) { ... }
(在列表的情况下)或while (my $f = ...) { ... }
(在迭代器的情况下)。您使用的glob表达式(/etc/puppet/nodes/*.pp
)可以通过glob
function glob '/etc/puppet/nodes/*.pp'
在Perl中进行评估。
与一些风格改进一起:
use strict; use warnings;
use autodie; # automatic error handling
while (defined(my $file = glob '/etc/puppet/nodes/*.pp')) {
open my $fh, "<", $file; # lexical file handles, automatic error handling
while (defined( my $line = <$fh> )) {
do stuff;
}
close $fh;
}
然后:
$ /etc/puppet/nodes/brackets.pl
答案 1 :(得分:5)
这不是你提出的要求,但另一种可能性是使用<>
:
while (<>) {
my $line = $_;
# do stuff
}
然后你将文件名放在命令行上,如下所示:
/etc/puppet/nodes/brackets.pl /etc/puppet/nodes/*.pp
Perl会为您打开和关闭每个文件。 (在循环内部,当前文件名和行号分别为$ARGV
和$.
。)
答案 2 :(得分:2)
Jason Orendorff有正确答案:
null文件句柄&lt;&gt;很特别:它可以用来模拟sed和awk的行为,以及任何其他带有文件名列表的Unix过滤器程序,对所有输入的每一行做同样的事情。来自&lt;&gt;的输入来自标准输入,或来自命令行中列出的每个文件。
这不需要opendir
。它不需要在程序中使用globs
或硬编码。这是读取命令行中所有文件或从STDIN传输到程序中的所有文件的自然方式。
有了这个,你可以这样做:
$ myprog.pl /etc/puppet/nodes/*.pp
或
$ myprog.pl /etc/puppet/nodes/*.pp.backup
甚至:
$ cat /etc/puppet/nodes/*.pp | myprog.pl
答案 3 :(得分:1)
看看this documentation它解释了你需要知道的所有内容
#!/usr/bin/perl
use strict;
use warnings;
my $dir = '/tmp';
opendir(DIR, $dir) or die $!;
while (my $file = readdir(DIR)) {
# We only want files
next unless (-f "$dir/$file");
# Use a regular expression to find files ending in .pp
next unless ($file =~ m/\.pp$/);
open (FILE, '<', $file) || die "Unable to open $file\n";
while (defined (my $line = <FILE>)) {
# do stuff
}
}
closedir(DIR);
exit 0;
答案 4 :(得分:1)
我建议将所有文件名放到数组中,然后将此数组用作perl方法或脚本的参数列表。请参阅以下代码:
use Data::Dumper
$dirname = "/etc/puppet/nodes";
opendir ( DIR, $dirname ) || die "Error in opening dir $dirname\n";
my @files = grep {/.*\.pp/} readdir(DIR);
print Dumper(@files);
closedir(DIR);
现在您可以将\ @files作为参数传递给任何perl方法。
答案 5 :(得分:0)
my @x = <*>;
foreach ( @x ) {
chomp;
if ( -f "$_" ) {
print "process $_\n";
# do stuff
next;
};
};
答案 6 :(得分:-2)
Perl可以以各种方式执行系统命令,最直接的是使用反引号``
use strict;
use warnings FATAL => 'all';
my @ls = `ls /etc/puppet/nodes/*.pp`;
for my $f ( @ls ) {
open (my $FILE, '<', $f) || die "Unable to open $f\n";
while (defined (my $line = <$FILE>)) {
# do stuff
}
close $FILE;
}
(注意:您应始终 use strict;
和use warnings;
)