Perl에서 표준 입력을 수신하는 파일 핸들을 어떻게 재설정하려면?
문제
PERL 스크립트를 발행하면 일부 표준 입력 (예 :
$ awk '{print $1"\t"$2}' foo.txt | myScript.pl
버그가 포함 된 스크립트가 있습니다. 표준 입력의 첫 번째 줄을 읽고, 첫 번째 줄에서 무언가를 가져오고, 후속 읽기에서 표준 입력의 라인 2에서 n을 구문 분석합니다.
open (FH, "< $input") or die $?;
my $firstLine = <FH>; // reads first line
...
while (my $line = <FH>) {
// reads lines 2 through n
}
close (FH);
그래서 나는 a를 추가했다 seek
파일 핸들을 파일의 시작 부분으로 재설정하려는이 스크립트에 대한 명령문.
use Fcntl qw(:seek);
...
open (FH, "< $input") or die $?;
my $firstLine = <FH>; // reads first line
seek (FH, 0, SEEK_SET) or die "error: could not reset file handle\n"; // should reset file handle
...
while (my $line = <FH>) {
// reads lines 1 through n (in theory)
}
close (FH);
이것을 추가합니다 seek
명령문은 파일 입력에 대해서는 작동하지만 표준 입력에는 그렇지 않습니다. 스크립트는 오류와 함께 충돌합니다.
error: could not reset file handle
스크립트 시작시 첫 번째 표준 입력 라인을 올바르게 읽고 파일 핸들을 재설정 한 다음 표준 입력의 모든 줄 1에서 n을 읽을 수 있습니까?
나는 첫 번째 줄을 저장하고 처리하는 특별한 사례를 쓸 수 있다고 생각합니다. while
루프이지만 표준 입력과 파일 입력을 모두 처리 할 수있는이 문제에 대한 더 깨끗한 솔루션이 있기를 바랍니다.
해결책
쉬운 방법이 있습니다 :
open (FH, "< $input") or die $?;
my $line = <FH>; // reads first line
//do stuff with first line
do {
//stuff
} while ($line = <FH>);
다른 팁
편집하다: 첫 번째 접근 방식의 단점은 모든 라인을로드해야한다는 것입니다. FH
목록을 처리하기 전에 메모리에. 이 접근법은 개방형 스칼라 참조 기능 (5.8.0 이후 사용 가능)을 사용하여 해당 문제가 없습니다.
my $firstline = <FH>;
open(my $f1, '<', \$firstline);
...
while (my $line = <$f1> || <FH>) {
# process line 1 through n
}
어때요 :
for my $line ($firstline, <FH>) {
# process lines 1 through n
}
나는 당신이 stdin을 위해 재설정 (또는 추구) 할 수 있다고 생각하지 않습니다. Stdin과 같은 일반적인 파일 핸들이 아닙니다. 실제로 파일이 아니기 때문에 stdin이 재설정 가능한 버퍼링을 요구할 것입니다.
1 행 1의 독서 및 재사용을 특별히 처리해야한다고 생각합니다.