简体   繁体   中英

How to execute Perl one liner inside Perl script

I want to execute below one liner in Perl script, to match a line with the values of variables owner and type and delete it from the file:

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

Content of /tmp/test :

node01    A    10.10.10.2
node02    A    10.20.30.1

This works perfectly fine when I execute in shell, but the same does not work in a Perl script.

I have tried to use backticks, system and exec . Nothing seems to work.

`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));

Is it possible to execute Perl one liners inside a Perl script?

If so, what am I doing wrong here?

Note: I don't need solution to delete a line from a file with sed, grep, awk etc.

You wouldn't want to generate Perl code from the shell, so you'd use one of the following from the 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

or

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

The Perl equivalents are

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

and

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',
);

Rather than calling a one-liner, you could emulate the -i and -n flags. -n just requires a while loop. -i involves creating and writing to a temporary file and then renaming it to the input file.

To choose the temporary filename, you could use /tmp/scriptname.$$ which appends the processId to a basename of your choice. A more sophisticated solution could use 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";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM