История изменений
Исправление aureliano15, (текущая версия) :
prog | sed выводит в реальном времени, а с awk нет
и
Всё таки это awk тормозит.
Весьма странно. awk не должна тормозить в такой ситуации даже на слабом компе, а буфер в моём однострочнике точно ни при чём.
Я думаю всё таки поможет read, который вы описали выше.
Попробуйте вместо awk подставить такой bash скрипт:
#!/bin/bash
while true;
do
read var;
if [ "$(echo $var | grep -F '.')" ];
then
vari="$(echo -n $var | sed 's/\..*//')";
varf="$(echo -n $var | sed 's/.*\.//')";
else
if [ -n "$var" ];
then
vari=$var;
varf=0;
else
# Если вместо continue поставить break,
# то при встрече пустой строки скрипт прервётся:
continue;
fi;
fi;
if [ -z "$vari" ];
then
vari=0;
fi;
echo -n "$var: ";
if [ "$vari" -gt -100 -a "$vari" -lt 100 ];
then
echo Ok.;
else
if [ "$vari" -lt -100 -o "$vari" -gt 100 -o "$varf" -gt 0 ];
then
echo Alert.;
else
echo Ok.;
fi;
fi;
done
Этот скрипт учитывает цифры и после точки.
Можно ещё попробовать вместо awk, скрипта и sed’а такую c-программку:
#include <stdio.h>
#include <stdlib.h>
int main()
{
double n;
char *ptr, *endptr, buf[4096];
while(!feof(stdin))
{
if((endptr=fgets(buf, sizeof(buf), stdin))!=NULL)
{
do
{
ptr=endptr;
n=strtod(ptr, &endptr);
if(endptr && endptr!=ptr)
printf("%f: %s.\n", n, n<-100.0 || n>100.0 ? "Alert" : "Ok");
} while(*endptr && endptr!=ptr);
}
}
return 0;
}
Компилируете её командой gcc -o alert100 -Wall -O3 -g0 alert100.c
, где alert100.c — название исходника, а alert100 — название выходной исполняемой программы, вместо них можно придумать свои названия. И затем запускаете командой prog | ./alert100
. Программа умеет читать по нескольку чисел из строки, поэтому sed ей не нужен. Массив buf для входной строки я установил в 4096. Если строки могут быть больше, то нужно увеличить это число. Если же строки абсолютно всегда намного меньше, то можно уменьшить, но так, чтоб помимо строки в buf помещалось ещё по меньшей мере 2 символа: символ новой строки и 0. В выводе программы есть одно отличие: числа с большим числом 0 после точки округляются при выводе, но не при сравнениях, из-за чего иногда можно увидеть что-то вроде:
-100.000000: Alert.
100.000000: Alert.
-100.000000: Ok.
100.000000: Ok.
Чтоб Alert и Ok соответствовали выводимому числу в таких случаях, достаточно увеличить точность вывода с помощью флагов форматирования в функции printf.
Обязательно отпишитесь, помогли или не помогли эти варианты. Потому что самому стало интересно, что у вас там с awk происходит.
Мне нужно что бы alert запускался одноразово и сценарий закрывался.
Этого в исходной формулировке задачи не было. Для этого в bash и awk есть команда exit
, а в языке си — оператор return
.
Исходная версия aureliano15, :
prog | sed выводит в реальном времени, а с awk нет
и
Всё таки это awk тормозит.
Весьма странно. awk не должна тормозить в такой ситуации даже на слабом компе, а буфер в моём однострочнике точно ни при чём.
Я думаю всё таки поможет read, который вы описали выше.
Попробуйте вместо awk подставить такой bash скрипт:
#!/bin/bash
while true;
do
read var;
if [ "$(echo $var | grep -F '.')" ];
then
vari="$(echo -n $var | sed 's/\..*//')";
varf="$(echo -n $var | sed 's/.*\.//')";
else
if [ -n "$var" ];
then
vari=$var;
varf=0;
else
# Если вместо continue поставить break,
# то при встрече пустой строки скрипт прервётся:
continue;
fi;
fi;
if [ -z "$vari" ];
then
vari=0;
fi;
echo -n "$var: ";
if [ "$vari" -gt -100 -a "$vari" -lt 100 ];
then
echo Ok.;
else
if [ "$vari" -lt -100 -o "$vari" -gt 100 -o "$varf" -gt 0 ];
then
echo Alert.;
else
echo Ok.;
fi;
fi;
done
Этот скрипт учитывает цифры и после точки.
Можно ещё попробовать вместо awk, скрипта и sed’а такую c-программку:
#include <stdio.h>
#include <stdlib.h>
int main()
{
double n;
char *ptr, *endptr, buf[4096];
while(!feof(stdin))
{
if((endptr=fgets(buf, sizeof(buf), stdin))!=NULL)
{
do
{
ptr=endptr;
n=strtod(ptr, &endptr);
if(endptr && endptr!=ptr)
printf("%f: %s.\n", n, n<-100.0 || n>100.0 ? "Alert" : "Ok");
} while(*endptr && endptr!=ptr);
}
}
return 0;
}
Компилируете её командой gcc -o alert100 -Wall -O3 -g0 alert100.c
, где alert100.c — название исходника, а alert100 — название выходной исполняемой программы, вместо них можно придумать свои названия. И затем запускаете командой prog | ./alert100
. Программа умеет читать по нескольку чисел из строки, поэтому sed ей не нужен. Массив buf для входной строки я установил в 4096. Если строки могут быть больше, то нужно увеличить это число. Если же строки абсолютно всегда намного меньше, то можно уменьшить, но так, чтоб помимо строки в buf помещалось ещё по меньшей мере 2 символа: символ новой строки и 0. В выводе программы есть одно отличие: числа с большим числом 0 после точки округляются при выводе, но не при сравнениях, из-за чего иногда можно увидеть что-то вроде:
-100.000000: Alert.
100.000100: Alert.
-100.000000: Ok.
100.000100: Ok.
Чтоб Alert и Ok соответствовали выводимому числу в таких случаях, достаточно увеличить точность вывода с помощью флагов форматирования в функции printf.
Обязательно отпишитесь, помогли или не помогли эти варианты. Потому что самому стало интересно, что у вас там с awk происходит.
Мне нужно что бы alert запускался одноразово и сценарий закрывался.
Этого в исходной формулировке задачи не было. Для этого в bash и awk есть команда exit
, а в языке си — оператор return
.