다음 Perl 스크립트는 consume-10-lines-and-exit
stdin에서 10줄을 읽고 인쇄합니다. 그 후에는 종료됩니다.
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
for (my $i = 0; $i < 10; $i++) {
my $line = <STDIN>;
print $line;
}
입력 합계의 처음 10줄이 소비되고 첫 번째 명령에 의해 인쇄된 다음 나머지가 소비되는 방식으로 consume-10-lines-and-exit
합계를 결합하려고 합니다 .cat
cat
아래 코드 조각은 예상한 대로 1~13 대신 1~10을 모두 인쇄합니다.
printf '1 2 3 4 5 6 7 8 9 10 11 12 13' \
| tr ' ' '\n' | { perl consume-10-lines-and-exit; cat; }
printf '1 2 3 4 5 6 7 8 9 10 11 12 13' \
| tr ' ' '\n' | ( perl consume-10-lines-and-exit; cat )
printf '1 2 3 4 5 6 7 8 9 10 11 12 13' \
| tr ' ' '\n' | sh -c 'perl consume-10-lines-and-exit; cat'
명령이 종료될 때까지 stdin에서 입력을 읽은 다음 이전 명령이 중단된 곳에서 다음 명령이 계속되도록 명령을 정렬하는 구조가 있습니까?
답변1
문제는 Perl이 버퍼링된 입력을 사용하므로 사용하려는 것보다 더 많은 행을 미리 읽는다는 것입니다. 다음 바이트 단위 버전을 사용해 보세요.
perl -e '
use strict;
use warnings FATAL => "all";
for (my $i = 0; $i < 10; $i++) {
my $line;
while(sysread(*STDIN,my $char,1)==1){
$line .= $char;
last if $char eq "\n";
}
print $line;
}'
답변2
그룹 명령을 사용하는 것이 해당 작업에는 적합하지만, 그룹 명령에 입력한 입력 내용이 검색되지 않는 것이 원인입니다.
POSIX에 정의됨INPUT FILE
부분:
표준 유틸리티가 검색 가능한 입력 파일을 읽고 파일 끝에 도달하기 전에 오류 없이 종료되는 경우 유틸리티는 열린 파일 설명의 파일 오프셋이 유틸리티가 처리한 마지막 바이트 뒤에 올바르게 위치하는지 확인해야 합니다. 검색 불가능한 파일의 경우 파일의 열린 파일 설명에 파일 오프셋 상태가 지정되지 않습니다.
perl
표준 유틸리티는 아니지만 표준 사양을 따를 가능성이 높습니다. 파일을 검색 가능하게 설정하면 다음과 같이 작동합니다.
$ seq 13 > /tmp/test
$ {perl -e 'for($i=0;$i<10;$i++){$line = <STDIN>;print $line}'; cat;} </tmp/test
1
2
3
4
5
6
7
8
9
10
11
12
13
검색 가능한 파일을 사용하지 않으려면 IO에 대해 하위 수준 시스템 호출 함수 , 를 perl
사용하도록 강제할 수 있습니다.read()
write()
lseek()
$ seq 13 | {
PERLIO=:unix perl -e 'for($i=0;$i<10;$i++){$line = <STDIN>;print $line}'
cat
}
답변3
버퍼링은 다음을 조작하여 비활성화할 수도 있습니다.펄IO레이어(또한 참조페렌). 게다가 어색하고 긴 C 스타일 루프는 ... for 1..10
또는 로 더 쉽게 작성할 수 있습니다 for my $i (1..10) { ... }
.
$ perl -E 'say for 1..12' \
| ( PERLIO=:unix perl -e 'print "perl " . scalar <STDIN> for 1..10'; cat )
perl 1
perl 2
perl 3
perl 4
perl 5
perl 6
perl 7
perl 8
perl 9
perl 10
11
12
$