쉘에서 "perl 명령"을 실행하고 시스템 명령을 사용하여 Perl 스크립트에서 동일한 명령을 실행하십시오.

쉘에서 "perl 명령"을 실행하고 시스템 명령을 사용하여 Perl 스크립트에서 동일한 명령을 실행하십시오.

특수 문자를 처리할 수 없습니다.

다음 Perl 스크립트가 있습니다.

while(@mapping_array[$i])
{  
  chomp(@mapping_array[$i]);
  my @core= split ( /  / , $mapping_array[$i]) ;
  @core[0] =~ tr/ //ds ;   ## Deleting blank spaces
  @core[1] =~ tr/ //ds ;     
  system("perl -pi -e 's/@core[0]/@core[1]/' $testproc ");  
  print "@core[0] \n";
  print "@core[1] \n";
  $i++;
}

문제는 내 @core[0]변수가 단순한 문자열(예를 들어)일 수도 abc있고 더 복잡한 문자열(예를 들어) 일 수도 있다는 것입니다 TEST[1]. 내 스크립트는 예상대로 작동하여 abc해당 값을 값으로 바꾸지만 , 내 스크립트가 실패 @core[1]하면 스크립트가 실패합니다 .@core[0]TEST[1]

대신 대체 연산자를 사용하면 ?도움이 되지 않습니다. /어떻게 하면 올바르게 할 수 있나요?

답변1

당신이 찾고 있는 것 같군요 quotemeta. 설명된 대로 perldoc -f quotemeta:

quotemeta EXPR
        Returns the value of EXPR with all the ASCII non-"word" characters
        backslashed. (That is, all ASCII characters not matching
        "/[A-Za-z_0-9]/" will be preceded by a backslash in the returned
        string, regardless of any locale settings.) This is the internal
        function implementing the "\Q" escape in double-quoted strings.

따라서 스크립트는 다음과 같습니다(배열 요소는 가 $foo[N]아닌 으로 지정되어야 합니다 @foo[N]).

chomp(@mapping_array);
while($mapping_array[$i])
{  
    my @core= split ( /  / , $mapping_array[$i]) ;
    $core[0] =~ tr/ //ds ;   ## // Deleting blank spaces
    $core[1] =~ tr/ //ds ;   # / fix SO highlighting
    my($k,$l)=(quotemeta($core[0]),quotemeta($core[1]))
    system("perl -pi -e 's/$k/$l/' $testproc "); 
    print "$core[0] \n$core[1] \n";
    $i++;
}

답변2

Perl에서 Perl을 실행하는 것은 일반적으로 피할 수 있습니다.

for my $both (@mapping) {
    my ($regex, $replace) = split /  /, $both;
    tr/ //ds for $regex, $replace;                                                                   # // Fix SO highlighting bug.

    open my $IN,  '<', $testproc or die $!;
    open my $OUT, '>', "$testproc.new" or die $!;
    while (<$IN>) {
        s/\Q$regex/$replace/;
        print {$OUT} $_;
    }
    close $OUT or die $!;
    rename $testproc, "$testproc.old" or die $!;
    rename "$testproc.new", $testproc or die $!;
}

\Q는 다음에 해당합니다.참조 요소이렇게 하면 $regex 변수의 특수 문자가 해석되지 않습니다.

답변3

첫 번째 - 프로그램 상단에서 strict열기 :warnings

use strict;
use warnings;

@core[0]이는 실제로 잘못된 오류 와 같은 오류를 식별하는 데 도움이 됩니다 .

그러나 두 번째 문제는 정규식에 메타 문자를 보내는 것입니다. 이는 []정규식에 특별한 것이 있음을 의미합니다.

그래서 정말로 필요한 것은 quotemeta기능성입니다.

print quotemeta '@core[0]';

이것은 다음과 같이 변합니다:

\@core\[0\]

또는

print quotemeta $core[0]; 

제공한 예에서는 다음과 같이 인쇄됩니다.

TEST\[1\]

물론 system()내부에서도 호출할 필요는 없을 것입니다. 그것은 비효율적이고 혼란스러울 뿐입니다. perlperl

답변4

\Q문자의 특별한 의미를 제거하려면 정규 표현식에 사용하세요 .

system("perl -pi -e 's/\\Q$core[0]/$core[1]/' $testproc ");

관련 정보