我玩过缓冲设置无济于事,所以我的结论是read
在完成之前等待换行符。如果您改为read -n1
,read
将只读取一个字符,这也不是我们想要的,因为 then$line
将始终只是那个字符。
不幸的是,grep
似乎具有相同的行为(即使更改了缓冲选项),即使grep -o
:
$ tail logfile -f -n0 | grep -o test &
[1] 25524
$ echo -n test >> logfile
$ echo -n test >> logfile
$ echo test >> logfile
test
test
test
我认为一般的解决方案是推出我们自己的“环形缓冲区 grep”搜索工具,将每个字符的字符读入环形缓冲区。
这是我的perl版本,希望对您有所帮助。(另存为ringgrep.pl
:)
#!/usr/bin/perl -w
use strict;
if (!$ARGV[0]) {
print "Usage: $0 needle\n";
exit 1;
}
my $needle = $ARGV[0];
my $buffer_len = length($needle);
my @buffer = (0) x $buffer_len;
my $i = 0;
my $input;
while(sysread(STDIN, $input, 1)) {
$buffer[$i] = $input;
my $string = join("", @buffer);
$string = (($i+1)%$buffer_len == 0 ? "" : substr($string, $i-$buffer_len+1)) . substr($string, 0, $i+1);
# print "string is: $string\n";
if ($string =~ /$needle/) {
print "got test!\n";
@buffer = (0) x $buffer_len;
$i = 0
} else {
$i = (++$i) % $buffer_len
}
}
用法:
$ chmod +x ringgrep.pl
$ tail logfile -n0 -f | ./ringgrep.pl "this is a test" &
[1] 25756
$ echo -n "test" >> logfile
$ echo -n "test" >> logfile
$ echo -n "test" >> logfile
$ echo -n "test" >> logfile
$ echo -n "this is a test" >> logfile
got test!
$ echo -n "this is a test" >> logfile
got test!
$ echo -n "this is a test" >> logfile
got test!
$ (echo -n t; echo -n h; echo -n i; echo -n s; echo -n ' '; echo -n i; echo -n s; echo -n ' '; echo -n a; echo -n ' '; echo -n t; echo -n e; echo -n s; echo -n t) >> logfile
got test!