6

ファイルがあります:

:~$ cat fff
qwerty
asdf
qwerty
zxcvb

スクリプトがあります:

:~$ cat 1.pl
#!/usr/bin/perl
print <STDIN>

コマンドは期待どおりに機能します。

:~$ cat fff | perl -e 'system("./1.pl")'
qwerty
asdf
qwerty
zxcvb

しかし、このコマンドは期待どおりには機能しません。最初の <STDIN> は、1 行ではなく、すべてのデータを読み取ります。<STDIN> のバッファリングを無効にする方法は?

:~$ cat fff | perl -e '$_ = <STDIN>; system("./1.pl")'
:~$
4

3 に答える 3

6

ここには 2 つの Perl プロセスがあり$_ = <STDIN>ますsystemprint <STDIN>

ストリームの最初の行のみが最初のプロセスによって読み込まれますが$_、舞台裏で Perl はバッファをデータで満たし、ストリームを空のままにしています。

これの目的は何ですか?あなたが求めていることを実行するために頭に浮かぶ唯一の方法は、最初のプロセスですべてのファイルを配列に読み込み、次に最初の行を削除して残りをパイプで 2 番目のスクリプトに送信することです

これはすべて不必要に思えます。根本的な問題を説明していただければ、より良い方法があると確信しています。

アップデート

バッファリングの問題を認識していると言うので、これを行う方法は を使用することです。これsysreadにより、パイプから下位レベルで読み取り、バッファリングを回避します

このようなものが機能します

cat fff | perl -e 'while (sysread(STDIN, $c, 1)) {$_ .= $c; last if $c eq "\n"} system("./1.pl")'

しかし、あなたがしていることは非常に間違っているように見えるので、私はそれをお勧めしたくありません.あなたの本当の目標を説明してほしい.

于 2012-09-10T12:29:58.913 に答える
0

最近、それぞれ約 6 ギガバイトのいくつかのログ ファイルを解析する必要がありました。STDIN を配列に割り当てると、Perl は喜んで 6 ギガバイトをメモリに読み込もうとするため、バッファリングが問題でした。私は次の回避策を思いつきました。ファイルを 1 行ずつ読み取るだけで、大量のメモリのブラックホール バッファリングの渦を回避できます。そうしないと、すべてのシステム リソースが奪われてしまいます。

注: このスクリプトが行うのは、6 ギガバイトのファイルをいくつかの小さなファイルに分割することだけです (サイズは、各出力ファイルに含まれる行数によって決まります)。興味深い点は、while ループと、ログ ファイルから変数への 1 行の割り当てです。ループは、ファイル全体を反復して 1 行を読み取り、それに対して何かを実行してから繰り返します。結果、大規模なバッファリングはありません...実際の例を示すためだけに、スクリプト全体をそのまま残しました...

#!/usr/bin/perl -w
BEGIN{$ENV{'POSIXLY_CORRECT'} = 1;}
use v5.14;
use Getopt::Long qw(:config no_ignore_case);

my $input = '';
my $output = '';
my $lines = 0;
GetOptions('i=s' => \$input, 'o=s' => \$output, 'l=i' => \$lines);

open FI, '<', $input;

my $count = 0;
my $count_file = 1;
while($count < $lines){
    my $line = <FI>; #assign a single line of input to a variable
    last unless defined($line);
    open FO, '>>', "$output\_$count_file\.log";
    print FO $line;
    $count++;
    if($count == $lines){
        $count=0;
        $count_file++;
    }
}
print " done\n";

スクリプトは、次のようにコマンド ラインで呼び出されます。

(スクリプト名) -i (入力ファイル) -o (出力ファイル) -l (出力ファイルのサイズ(行数))

探しているものとまったく同じでなくても、いくつかのアイデアが得られることを願っています。:)

于 2013-01-24T10:28:54.347 に答える