【问题标题】:How to execute Perl one liner inside Perl script如何在 Perl 脚本中执行 Perl 一行
【发布时间】:2015-12-29 15:16:29
【问题描述】:

我想在 Perl 脚本中的一行下面执行,以匹配变量 ownertype 的值并将其从文件中删除:

perl -i -ne\"print unless /\b${owner}\b/ and /\b${type}\b/;\" /tmp/test

/tmp/test的内容:

node01    A    10.10.10.2
node02    A    10.20.30.1

当我在 shell 中执行时,这工作得很好,但在 Perl 脚本中却不工作。

我尝试使用反引号systemexec。似乎没有任何效果。

`perl -i -ne\"print unless /\b${owner}\b/ and /\b${type}\b/;\" /tmp/test`

system(q(perl -i -ne\"print unless /\b${owner}\b/ and /\b${type}\b/;\" /tmp/test));

是否可以在 Perl 脚本中执行 Perl one liner?

如果是这样,我在这里做错了什么?

注意:我不需要使用 sed、grep、awk 等从文件中删除一行的解决方案。

【问题讨论】:

  • 您应该打印出您尝试执行的命令,然后您应该会看到问题:print q(perl -i -ne\"print unless /\b${owner}\b/ and /\b${type}\b/;\" /tmp/test);
  • 还可以查看 perldoc perlop 中的 q{}
  • 既然已经在 perl 中,为什么还要运行另一个 perl?阅读perlrun 以了解-i-n 的作用——您可以轻松地复制它们。 -i 可能看起来很大,但实际上你并不需要大部分。
  • 老实说,我建议“不要”。充其量是令人困惑的。只需将其扩展 - perl -MO=Deparse 将为您完成一定数量的工作,因此您将获得更快、更清晰的脚本。一个班轮很方便,但他们不是很好的编程风格

标签: perl


【解决方案1】:

您不想从 shell 生成 Perl 代码,因此您可以从 shell 中使用以下代码之一:

perl -i -ne'
   BEGIN { $owner = shift; $type = shift; }
   print unless /\b\Q$owner\E\b/ and /\b\Q$type\E\b/;
' "$owner" "$type" /tmp/test

ARG_OWNER="$owner" ARG_TYPE="$type" perl -i -ne'
   print unless /\b\Q$ENV{ARG_OWNER}\E\b/ and /\b\Q$ENV{ARG_TYPE}\E\b/;
' /tmp/test

Perl 等价物是

system('perl',
   '-i',
   '-n',
   '-e' => '
      BEGIN { $owner = shift; $type = shift; }
      print unless /\b${owner}\b/ and /\b${type}\b/;
   ',
   $owner,
   $type,
   '/tmp/test',
);

local $ENV{ARG_OWNER} = $owner;
local $ENV{ARG_TYPE}  = $type;
system('perl',
   '-i',
   '-n',
   '-e' => 'print unless /\b\Q$ENV{ARG_OWNER}\E\b/ and /\b\Q$ENV{ARG_TYPE}\E\b/;',
   '/tmp/test',
);

【讨论】:

    【解决方案2】:

    您可以模拟-i-n 标志,而不是调用单行。 -n 只需要一个 while 循环。 -i 涉及创建和写入临时文件,然后将其重命名为输入文件。

    要选择临时文件名,您可以使用 /tmp/scriptname.$$ 将 processId 附加到您选择的基本名称。更复杂的解决方案可以使用File::Temp

    open(IN, "<$file") || die "Could not open file $file";
    open(OUT, ">$out") || die "Could not create temporary file $out";
    while(<IN>) {
        print OUT $_ unless /\b$owner\b/ and /\b$type\b/;    
    }
    close(IN);
    close(OUT) || die "Could not close temporary file $out";
    rename($out, $file) || die "Failed to overwrite $file";
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-05
      • 1970-01-01
      • 2013-07-13
      • 1970-01-01
      • 2015-03-15
      • 2010-09-26
      • 1970-01-01
      相关资源
      最近更新 更多