У меня есть файл, в котором непрерывно добавляются числа:
1
2
3
4
Я хочу вычислить их среднее значение, также непрерывно, то есть:
1
1.5
2
2,5
Я не хочу периодически проверять файл, я хочу, чтобы он работал так же, как tail -f - как только добавляется строка, я выполняю средние вычисления.
Является ли это возможным?
UPD Вопрос перемещен в https://stackoverflow.com/questions/9400306/countinuous-processing-of-tail-f-output
Вот простое решение с использованием постоянного тока.
tail -f | dc -e '5k 0 d sc st [? lc 1 + sc lt + st lt lc / p c lax] sa lax'
Я не уверен, поддерживает ли dc хвостовую рекурсию, иначе эта программа будет вызывать утечку памяти. dc имеет действительно плохую документацию. :)
Что, тебе не нравится ебать мозги? :)
Вот простое решение на Ruby. tail -f | ruby -e 'sum=total=0.0; while line=gets; total += line.to_f; sum += 1; puts total/sum; end'
Да. Труба tail -f
в скрипт, который обрабатывает ваше усреднение. Канал никогда не закроется, и сценарий может мгновенно обработать каждую полученную строку ... он будет блокироваться, пока не появится строка.
Также следует иметь в виду, что можно рассчитать скользящее среднее без необходимости каждый раз складывать все значения. Я видел это достаточно, я чувствую необходимость упомянуть об этом.
#generator.pl
$| = 1; #immediate flush
while (1) {
print int rand(100), "\n";
sleep 1;
}
#average.pl
$| = 1; #immediate output flush
my $average = 0;
my $count = 0;
while (<>) {
$average = ($average * $count + $_) / ($count + 1);
$count++;
print $average, "\n";
}
$ perl generator.pl > source &
[2] 15564
(reverse-i-search)`': ^C
$ tail -f source | perl average.pl
54
28
27.6666666666667
35
41
И только для усмешек:
$tail -f source | awk '{total+=$0; count+=1; print total/count}'
Это также дает мгновенную обратную связь. Мне кажется, что ваша проблема связана с буферизацией приложения, которое записывает в файл, из которого читает tail.
Видеть http://www.pixelbeat.org/programming/stdio_buffering/ для информации об этом.