2016-10-13 9 views
0

빠른 처리를 위해 일부 텍스트를 펄 스크립트로 파이프 처리하기 위해 proc_open을 사용하고 있습니다. 텍스트에는 URL로 인코딩 된 문자열과 리터럴 공간이 포함됩니다. url로 인코딩 된 공간이 원시 텍스트에 나타날 때 펄 스크립트에 도달 할 때까지 리터럴 공간으로 디코딩되는 것처럼 보입니다. perl 스크립트에서는 문자 그대로의 공백 문자의 위치에 의존하기 때문에 이러한 원치 않는 공백이 출력을 엉망으로 만든다.php - 펄 프로세스에 대한 파이프 입력은 자동으로 URL 인코딩 된 문자열을 디코딩합니다.

왜 이런 일이 벌어지고 있으며 그런 일이 발생하지 않도록하는 방법이 있습니까?

관련 코드는 :

$descriptorspec = array(
    0 => array("pipe", "r"), 
    1 => array("pipe", "w"), 
); 
$cmd = "perl script.pl"; 
$process = proc_open($cmd, $descriptorspec, $pipes); 
$output = ""; 

if (is_resource($process)) { 
    fwrite($pipes[0], $raw_string); 
    fclose($pipes[0]); 
    while (!feof($pipes[1])) { 
     $output .= fgets($pipes[1]); 
    } 
    fclose($pipes[1]); 
    proc_close($process); 
} 

원시 텍스트 입력의 라인은 다음과 같은 :

key url\tvalue1\tvalue2\tvalue3 

내 입력의 형식을 변환하여 문제를 방지 할 수있을 것, 그러나 여러 가지 이유로 바람직하지 않으며, 해결하기보다는 우회하는 것이 핵심 문제입니다.

또한 펄 스크립트 STDIN 파이프에 쓰기 전에 즉시 원시 텍스트 (echo)를 검사했기 때문에 문제가 PHP 스크립트와 perl 스크립트 사이에서 발생하는 것으로 알고 있습니다. url로 인코딩 된 원시 문자열에 대한 perl 스크립트.

이제 아래 perl 스크립트를 추가했습니다. 기본적으로 미니 맵 축소 작업으로 바뀝니다.

use strict; 

my %rows; 
while(<STDIN>) { 
    chomp; 
    my @line = split(/\t/); 
    my $key = $line[0]; 
    if (defined @rows{$key}) { 
     for my $i (1..$#line) { 
      $rows{$key}->[$i-1] += $line[$i]; 
     } 
    } else { 
     my @new_row; 
     for my $i (1..$#line) { 
      push(@new_row, $line[$i]); 
     } 
     $rows{$key} = [ @new_row ]; 
    } 
} 

my %newrows; 
for my $key (keys %rows) { 
    my @temparray = split(/ /, $key); 
    pop(@temparray); 
    my $newkey = join(" ", @temparray); 
    if (defined @newrows{$newkey}) { 
     for my $i (0..$#{ $rows{$key}}) { 
      $newrows{$newkey}->[$i] += $rows{$key}->[$i] > 0 ? 1 : 0; 
     } 
    } else { 
     my @new_row; 
     for my $i (0..$#{ $rows{$key}}) { 
      push(@new_row, $rows{$key}->[$i] > 0 ? 1 : 0); 
     } 
     $newrows{$newkey} = [ @new_row ]; 
    } 
} 

for my $key (keys %newrows) { 
    print "$key\t", join("\t", @{ $newrows{$key} }), "\n"; 
} 
+0

'fwrite' 호출 전에'echo ($ raw_string)'을 쓰고 그 내용을 확인하십시오. – mob

+0

마지막 단락에서 언급했듯이 이미했습니다. 그래도 고마워! 필자는 필기 직전 날 문자열을 검사했다는 것을보다 명확하게 설명 할 것이다. – Cyan

+0

펄 스크립트는 무엇을합니까? 입력 데이터를 읽는 방법을 보여줄 수 있습니까? – xxfelixxx

답변

0

참고 사항 : 항상 가정을 확인하십시오. 수억 개의 입력 라인 어딘가에 실제로 URL 인코딩 된 공간이 있어야하는 문자 그대로의 공간이있었습니다. 그것들을 발견하는 데는 시간이 걸렸습니다. 왜냐하면 수 억 가지의 정확한 문자 적 ​​공간이 있었기 때문이었습니다.

죄송합니다.