2015-12-29 3 views
1

Я хочу, чтобы выполнить ниже одного лайнера в сценарии Perl, чтобы соответствовать линии со значениями переменных owner и type и удалить его из файла:Как выполнить Perl один лайнер внутри сценария Perl

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 

Это отлично работает, когда я исполняю в оболочке, но то же не работает в сценарии Perl.

Я попытался использовать backticks, system и exec. Ничто не работает.

`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?

Если да, то что я делаю неправильно здесь?

Примечание: не нужно решение, чтобы удалить строку из файла с SED, Grep, AWK и т.д.

+1

вы должны распечатать команду, которую вы пытаетесь выполнить, вы должны увидеть проблему, то: 'печать д (Perl -i -ne \" не печатать, если/\ б $ {владелец} \ б/и/\ b $ {type} \ b /; \ "/ tmp/test);' –

+1

Также посмотрите ['q {}'] (http://perldoc.perl.org/perlop.html#Quote-and -Quote-like-Operators) в perldoc perlop. –

+5

Зачем запускать другой perl, когда вы уже находитесь в perl? Прочтите 'perlrun', чтобы узнать, что' -i' и '-n' делают - они могут быть тривиально реплицированы самостоятельно. '-i' может выглядеть большим, но на самом деле вам не нужна большая часть его. –

ответ

5

Вы не хотели бы, чтобы сгенерировать код Perl из оболочки, так что вы будете использовать один из следующих элементов: оболочки

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

Вместо вызова Однострочник, вы могли бы подражать -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"; 
Смежные вопросы