【问题标题】:Why are Perl's $. and $ARGV behaving strangely after setting @ARGV and using <>为什么 Perl 的 $.并且 $ARGV 在设置 @ARGV 并使用 <> 后表现异常
【发布时间】:2013-05-17 20:13:22
【问题描述】:

我编写了一个 perl 程序,从命令行获取一个正则表达式,并在当前目录中递归搜索某些文件名和文件类型,对每个正则表达式进行 grep,并输出结果,包括文件名和行号。 [基本的 grep + 查找功能,我可以根据需要进入并自定义]

cat <<'EOF' >perlgrep2.pl
#!/usr/bin/env perl
$expr = join ' ', @ARGV;

my @filetypes = qw(cpp c h m txt log idl java pl csv);
my @filenames = qw(Makefile);

my $find="find . ";
my $nfirst = 0;
foreach(@filenames) {
    $find .= " -o " if $nfirst++;
    $find .= "-name \"$_\"";
}
foreach(@filetypes) {
    $find .= " -o " if $nfirst++;
    $find .= "-name \\*.$_";
}

@files=`$find`;

foreach(@files) {
    s#^\./##;
    chomp;
}

@ARGV = @files;

foreach(<>) {
    print "$ARGV($.): $_" if m/\Q$expr/;
    close ARGV if eof;
}
EOF

cat <<'EOF' >a.pl
print "hello ";
$a=1;
print "there";
EOF

cat <<'EOF' >b.pl
print "goodbye ";
print "all";
$a=1;
EOF

chmod ugo+x perlgrep2.pl
./perlgrep2.pl print

如果您将其复制并粘贴到终端中,您将看到:

perlgrep2.pl(36): print "hello ";
perlgrep2.pl(0): print "there";
perlgrep2.pl(0): print "goodbye ";
perlgrep2.pl(0): print "all";
perlgrep2.pl(0):     print "$ARGV($.): $_" if m/\Q$expr/;

这让我很惊讶。该程序似乎正在运行,除了 $.和 $ARGV 变量没有我预期的值。从变量的状态来看,当 perl 在 上执行循环的第一次迭代时,它已经读取了所有三个文件(总共 36 行)。这是怎么回事 ?怎么修 ?这是 Perl 5.12.4。

【问题讨论】:

    标签: perl argv line-numbers


    【解决方案1】:

    您在应该使用while(&lt;&gt;) 的地方使用foreach(&lt;&gt;)foreach(&lt;&gt;) 会将@ARGV 中的每个文件读入一个临时列表开始迭代之前。

    【讨论】:

    • 谢谢!我必须说我最近一直在阅读很多 perl 文档,但我没有阅读。
    • 啊,所以“for”在列表上下文中评估 ,它将整个文件读入列表,而在标量上下文中评估 ,读取下一行。
    猜你喜欢
    • 2022-07-14
    • 2014-01-24
    • 2021-11-14
    • 2012-10-20
    • 2020-04-16
    • 2020-02-22
    • 2015-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多