如何重置在 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);
因此,我向此脚本添加了一个 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
循环之前的第一行,但我希望有一个更清晰的解决方案来解决这个问题,使我能够处理标准输入和文件输入。
When I issue a Perl script some standard input, e.g.
$ awk '{print $1"\t"$2}' foo.txt | myScript.pl
I have a script which contains a bug. It reads the first line of standard input, gets something from that first line, and then only parses lines 2 through n of standard input on subsequent read:
open (FH, "< $input") or die $?;
my $firstLine = <FH>; // reads first line
...
while (my $line = <FH>) {
// reads lines 2 through n
}
close (FH);
So I added a seek
statement to this script to try to reset the file handle to the beginning of the file:
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);
Adding this seek
statement works for file input, but not for standard input. The script crashes with the error:
error: could not reset file handle
How can I correctly read the first line of standard input at the start of the script, reset the file handle and then read all lines 1 through n of the standard input?
I guess I can write a special case for storing and processing the first line before the while
loop, but I'm hoping there is a cleaner solution to this problem that allows me to handle both standard input and file input.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有一个简单的方法:
There's an easy way:
编辑:我的第一种方法的缺点是它必须在处理列表之前将所有行从
FH
加载到内存中。这种方法,使用开放标量参考功能(自 5.8.0 起可用)不会有这个问题:怎么样:
EDIT: Drawback of my first approach is that it must load all lines from
FH
into memory before processing the list. This approach, using the open to scalar reference feature (available since 5.8.0) won't have that problem:How about:
我认为您无法重置(或搜索(0))STDIN。它不是标准输入那样的普通文件句柄。由于它实际上不是一个文件,因此您需要 STDIN 进行可重置缓冲。
我认为你需要专门处理第一行的读取和重用。
I don't think you can reset (or seek(0)) for STDIN. It isn't a normal file handle as STDIN. Since it isn't actually a file, you would require the STDIN does resettable buffering.
I think you'll need to handle the reading and re-using of line 1 specially.