2つのコマンドでstdinの入力を順番に使用させるにはどうすればよいですか?

2つのコマンドでstdinの入力を順番に使用させるにはどうすればよいですか?

次のPerlスクリプトはconsume-10-lines-and-exitstdinから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合計を結合しようとしています。catcat

以下のコードスニペットは、期待どおりに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

バッファリングは、次の操作で無効にすることもできます。PerlIOレイヤー(また参照フェレン)。さらに、厄介で長い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
$ 

関連情報