どのように私はPerlで標準入力を受けるファイルハンドルをリセットすることができますか?
質問
私はPerlスクリプトにいくつかの標準入力を発行すると、例えばます。
$ awk '{print $1"\t"$2}' foo.txt | myScript.pl
私は、バグが含まれているスクリプトを持っています。これは、標準入力の最初の行を読み取り、その最初の行から何かを取得し、その後のみ、後続の読み出しに標準入力のNを介して行2を解析する
open (FH, "< $input") or die $?;
my $firstLine = <FH>; // reads first line
...
while (my $line = <FH>) {
// reads lines 2 through n
}
close (FH);
は、だから私は、ファイルの先頭にファイルハンドルをリセットしようとするために、このスクリプトに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
どのように私は正しく、スクリプトの開始時に、標準入力の最初の行を読んで、ファイルハンドルをリセットして、標準入力のnまでのすべての行1を読むことができますか?
私は私が保管して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のためにあなたがリセット(または(0)を求める)ことができるとは思いません。これはSTDINとして、通常のファイルハンドルではありません。それは、ファイルが実際にはないので、あなたはSTDINがリセットバッファリングを行う必要になります。
私はあなたが読書を処理し、再使用して、特別にライン1のために必要があると思います。