Я вижу проблему в следующем: чтобы отфильтровать STDIN
для сценария, используя внешнюю программу, которая запускается изнутри сценария, когда сценарий выполняется (т. Е. Не с конвейером). С IPC :: Run
use warnings;
use strict;
use feature 'say';
use IPC::Run qw(start pump finish);
my $filtered_in;
FILTER_IN: {
my @cmd = qw(a_filter.pl); # add filter's options/arguments
my $h = start \@cmd, \my $in, \$filtered_in;
while (<>) {
$in = $_;
pump $h while length $in;
# Wait for filter's output -- IF WANT to process lines as received
pump $h until $filtered_in =~ /\n\z/;
chomp $filtered_in; # process/use filter's output
$filtered_in .= '|'; # as it's coming (if needed)
}
finish $h or die "Cleanup returned: $?";
};
say $filtered_in // 'no input';
Это позволяет обрабатывать строки вывода фильтра по мере их выдачи. Если это не нужно, но мы хотим накапливать выходные данные фильтра на более поздний срок, тогда вам не нужен код под # Wait for...
Простейший тест с a_filter.pl
, например
use warnings;
use strict;
STDOUT->autoflush(1);
my $cnt = 0;
while (<>) { print "line ", ++$cnt, ": ", $_ }
, а затем запустить
echo "a\nfew\nlines" | script.pl
с выводом
line 1: a|line 2: few|line 3: lines|
из нашей обработки игрушек в script.pl
выше.
Это также отфильтрует ввод через файл,
script.pl < input.txt