빠른 처리를 위해 일부 텍스트를 펄 스크립트로 파이프 처리하기 위해 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";
}
'fwrite' 호출 전에'echo ($ raw_string)'을 쓰고 그 내용을 확인하십시오. – mob
마지막 단락에서 언급했듯이 이미했습니다. 그래도 고마워! 필자는 필기 직전 날 문자열을 검사했다는 것을보다 명확하게 설명 할 것이다. – Cyan
펄 스크립트는 무엇을합니까? 입력 데이터를 읽는 방법을 보여줄 수 있습니까? – xxfelixxx