以下 perl 脚本consume-10-lines-and-exit
从 stdin 读取十行并打印它们。之后它退出。
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
for (my $i = 0; $i < 10; $i++) {
my $line = <STDIN>;
print $line;
}
我试图以这样的方式组合consume-10-lines-and-exit
和 ,cat
即前十行输入和 被第一个命令消耗和打印,然后其余的被 消耗cat
。
下面的代码片段全部打印 1 到 10,而不是像我预期的那样打印 1 到 13。
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
如果你不想使用可查找文件,你可以强制perl
使用下层调用系统调用函数read()
, write()
,lseek()
进行 IO:
$ seq 13 | {
PERLIO=:unix perl -e 'for($i=0;$i<10;$i++){$line = <STDIN>;print $line}'
cat
}