我有一个perl脚本,它从另一个进程读取输出(逐行),进行一些处理并吐出结果:
#!/bin/bash
set -e
set -o pipefail
RUN.SH ${@} 2>&1 | perl -M"Term::ANSIColor" -wnl -e '
m/ERROR/i and print "\e[1;91m", "$_", "\e[0m"
or print;'
除非流程RUN.SH
的输出不以新行(\n
结尾)结束,而是以\r
结尾,否则效果很好!在这种情况下,此Perl解析器在下一个\n
之前不会打印任何内容。我需要更改它,以便它同时使用\n
和\r
作为输入记录分隔符。
有什么想法吗?
答案 0 :(得分:3)
有四种方法可以从文件中读取:
getc
readline
$/ = $terminator;
read
和readline
$/ = \$length;
sysread
getc
可行,但我会使用效率更高的sysread
。
perl -we'
sub make_iter {
my ($fh) = @_;
my $buf = "";
my $eof = 0;
return sub {
return if $eof;
while (1) {
return $1 if $buf =~ s/^([^\r\n]*[\r\n])//;
my $rv = sysread(STDIN, $buf, 64*1024, length($buf));
if (!$rv) {
$eof = 1;
die $! if !defined($rv);
return $buf if length($buf);
return;
}
}
};
}
binmode(STDIN);
binmode(STDOUT);
$| = 1;
my $iter = make_iter(\*STDIN);
while (my ($line) = $iter->()) {
$line = "\e[1;91m" . $line . "\e[0m" if $line =~ /ERROR/i;
print($line);
}
'
答案 1 :(得分:0)
只需插入替换管段:
... | perl -pe's / \ r / \ n / g'| ...
RUN.SH ${@} 2>&1 | perl -pe 's/\r/\n/g' | perl -M"Term::ANSIColor" -wnl -e '
m/ERROR/i and print "\e[1;91m", "$_", "\e[0m"
or print;'
试验:
ivr@linux-e8sg:~> echo -e 'a\nb\rc\n'
a
c
ivr@linux-e8sg:~> echo -e 'a\nb\rc\n' | perl -pe 's/\r/\n/g'
a
b
c
答案 2 :(得分:-4)
哦,男孩,很多伟大而奇妙的剧本不正确。
'$ INPUT_RECORD_SEPARATOR'更改此默认值为'\ n'您可以在perl脚本本身中将其更改为您需要的内容。
您可以在perl special variables阅读更多内容,使用网络浏览器查找并搜索“INPUT_RECORD_SEPARATOR”