如何在BASH上下文中扩展Perl变量

时间:2013-03-07 10:08:46

标签: perl bash

好吧,问题标题可能有点令人困惑。我在下面的代码中复制了我的实际问题:

我创建的文件有两个不同的IP地址作为前缀,然后我想列出只有特定IP地址前缀的文件:

我正在创建带有“10.10.10.10”和“11.11.11.11”作为前缀的文件,然后我只想用“10.10.10.10”前缀列出文件。

这是我的代码:

#!/usr/bin/perl -w
use strict;

my $ipaddr1 = '10.10.10.10';
for ( my $counter = 1; $counter < 10; $counter++)
{
    my $filename = $ipaddr1."_".$counter.".txt";
    open (my $fh, ">", $filename) or die "$! \n";
}

my $ipaddr2 = '11.11.11.11';
for ( my $counter = 1; $counter < 10; $counter++)
{
    my $filename = $ipaddr2."_".$counter.".txt";
    open (my $fh, ">", $filename) or die "$! \n";
}
print "Done with creating hte files. \n";

print "Lets print the files with only 10.10.10.10 prefix \n";

for my $var ( `ls -1 $ipaddr1_*` )  ### <<< this is the probelm
{
    print $var;
}

输出

Global symbol "$ipaddr1_" requires explicit package name at test.pl line 21.
Execution of test.pl aborted due to compilation errors.

因此,我完全理解在执行bash命令时无法解释perl变量的错误。

问题

如何实现这一目标?我不想将显式IP地址传递给ls -1命令,而是希望传递包含相应IP地址的变量。

感谢。

3 个答案:

答案 0 :(得分:3)

问题在于Perl将下划线_解释为变量名称的一部分。最直接的解决方案是添加消除歧义的括号,以便不会发生这种情况:

`ls -1 ${ipaddr1}_*`

答案 1 :(得分:2)

Ilmari Karonen给出的${ipaddr1}_语法是正确的解决方案。还有一些其他方面可以改进:

  1. 不要为Perl已经可以执行的操作启动新进程:

    for my file (glob "${ipaddr1}_*") {
      print "$file\n";
    }
    

    这也更便携:)

  2. 请注意,open my $fh, ">", $filename会破坏文件。如果您只想创建不存在的文件但又不想破坏内容,请改用>>追加模式。

  3. 让您的生活更轻松,代码简短!使用循环和范围:

    for my $ipaddr ("10.10.10.10", "11.11.11.11") {
      for my $counter (1 .. 9) {
        my $filename = sprintf "%s_%d.txt", $ipaddr, $counter;
        open my $fh, ">", $filename or die "Can't open $filename: $!";
      }
    }
    

答案 2 :(得分:1)

<强>解决:

my $cmd = "ls -1 ". $ipaddr1."_*.txt";
for my $var ( `$cmd` )
{
    print $var;
}