Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Модератор: Модераторы разделов

dmitri22
Сообщения: 7
ОС: Windows, Linux

Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение dmitri22 »

Добрый день,

Подскажите, как написать быстрый shell-скрипт. Задача такая:
Имеется log файл, например:


------------- cut -----------------
LST_START Starting BAT_R001
AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag
LST_START Starting TIT_E001
[b]LST_START Starting TIT_E002
LST_START Starting SER_R001
LST_START Starting TGE_R001
Internal error: no page 4
Internal error: no page 4
Internal error: no page 4
Internal error: no page 4
LST_START Starting FRX_R002
LST_START Starting BAT_R001
AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag
LST_START Starting FRX_R001
LST_START Starting FRX_V002
LST_START Starting BAT_R001
AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag
LST_START Starting FRX_V001
LST_START Starting BAT_R001
-------------- cut -----------------

Нужно вывести этот лог в таком виде:

-------------- cut -----------------
LST_START Starting BAT_R001: AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag
LST_START Starting TGE_R001: Internal error: no page 4
LST_START Starting BAT_R001: AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag
LST_START Starting BAT_R001: AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag
-------------- cut -----------------

т.е. вывести сам заголовок "LST_START Starting TGE_R001:" и рядом ошибку "Internal error: no page 4". Где нет ошибок просто игнорировать. Сам скрипт я написал, проблем нет, но когда таких строк около 8-10 тыс, то скрипт работает о-о-очень долго! Может у кого-то есть другое решение? Вот сам скрипт:

Код:

#!/bin/ksh cat "$*" | while read LINE do t=`echo "$LINE" | grep "err" # для примера оставил err, а так файл с ошибками r=`echo "$LINE" | grep "LST_START Starting"` if [ -n "$r" ]; then bt="$r" fi if [ -n "$t" ]; then echo "$bt: $t" > ap_with_name_proc.txt fi : done cat ap_with_name_proc.txt | uniq > ap_with_name_proc_uniq.txt echo "done." exit 0
Спасибо сказали:
Аватара пользователя
Voice
Сообщения: 1073
Статус: столлманист
ОС: Debian GNU/Linux

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение Voice »

Для повышения производительности думаю лучше на Perl или другой подходящий язык переписать.
Как минимум не будет затрат на создание новых процессов...
"И может собственных Платонов и быстрых разумом Невтонов российская земля рождать."
М. В. Ломоносов
Спасибо сказали:
Аватара пользователя
minoru-kun
Сообщения: 621
ОС: Debian GNU/Linux

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение minoru-kun »

Код: Выделить всё

@contents = split 'LST_START', ( join ('', <STDIN>) );

foreach (@contents)
{
    $_ =~ s/\n//g;
    print "LST_START $_\n"
            if !( -z $_);
}
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5456
ОС: Gentoo

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение /dev/random »

sed -e 's/.*LST_START/\n\0/;$s/$/\n/' | sed -e ':a;/\n$/{s/\n/ /g;/.\{32\}/p;D};N;ba'

Здесь /.\{32\}/ - критерий, по которому определяется, следует ли показывать строку. Больше 30 символов - значит есть ошибки - значит нужно вывести. Вместо него можно прописать какое-нибудь другое условие, например, наличие слова error. Или вообще убрать условие, чтобы выводить всё.
Спасибо сказали:
dmitri22
Сообщения: 7
ОС: Windows, Linux

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение dmitri22 »

minoru-kun писал(а):
23.04.2008 17:17

Код: Выделить всё

@contents = split 'LST_START', ( join ('', <STDIN>) );

foreach (@contents)
{
    $_ =~ s/\n//g;
    print "LST_START $_\n"
            if !( -z $_);
}


Спасибо за скрипт, это видимо на Perl? Perl не знаю и соответственно вопрос, как заставить этот скрипт обрабатывать нужный файл, например, file.log?
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5456
ОС: Gentoo

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение /dev/random »

dmitri22 писал(а):
23.04.2008 17:30
Спасибо за скрипт, это видимо на Perl? Perl не знаю и соответственно вопрос, как заставить этот скрипт обрабатывать нужный файл, например, file.log?

Оба варианта - и его, и мой - обрабатывают stdin. Соответственно, файл обрабатвать так: cat file.log | скрипт
Спасибо сказали:
dmitri22
Сообщения: 7
ОС: Windows, Linux

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение dmitri22 »

/dev/random писал(а):
23.04.2008 17:17
sed -e 's/.*LST_START/\n\0/;$s/$/\n/' | sed -e ':a;/\n$/{s/\n/ /g;/.\{32\}/p;D};N;ba'

Здесь /.\{32\}/ - критерий, по которому определяется, следует ли показывать строку. Больше 30 символов - значит есть ошибки - значит нужно вывести. Вместо него можно прописать какое-нибудь другое условие, например, наличие слова error. Или вообще убрать условие, чтобы выводить всё.

Спасибо за ответ. Вот что получается после запуска sed

Код:

d@ubuntu:~/apsys$ sed -e 's/.*LST_START/\n\0/;$s/$/\n/' ap_with_err.txt | sed -e ':a;/\n$/{s/\n/ /g;/.\{32\}/p;D};N;ba' AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag Internal error: no page 41 AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag

Немного не тот результать.

Должно быть вот так:
LST_START Starting BAT_R001: AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag
LST_START Starting TGE_R001: Internal error: no page 4
LST_START Starting BAT_R001: AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag
LST_START Starting BAT_R001: AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag


работает быстро, вот что-то нужно подправить в sed, чтобы к каждой строке добавлялось "LST_START Starting BAT_R001".
Спасибо сказали:
dmitri22
Сообщения: 7
ОС: Windows, Linux

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение dmitri22 »

/dev/random писал(а):
23.04.2008 17:47
dmitri22 писал(а):
23.04.2008 17:30
Спасибо за скрипт, это видимо на Perl? Perl не знаю и соответственно вопрос, как заставить этот скрипт обрабатывать нужный файл, например, file.log?

Оба варианта - и его, и мой - обрабатывают stdin. Соответственно, файл обрабатвать так: cat file.log | скрипт

вот что получается:

Код:

d@ubuntu:~/apsys$ cat ap_with_err.txt | perl perl_script.pl LST_START AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag LST_START Starting TIT_E001 LST_START Starting TIT_E002 LST_START Starting CNP_R003 LST_START Starting OBI_E001 LST_START Starting WNK_I002 LST_START Starting API_I001 LST_START Starting TAB_R001 LST_START Starting USR_R001 LST_START Starting RUS_R001 LST_START Starting TEX_R001 LST_START Starting SER_R001 Internal error: no page 4001 LST_START Starting TRB_R001 LST_START Starting TRV_R001

а должно быть так:
красным выделил (выше), где идет заголовок "Starting SER_R001" и дальше в этой же строке должна быть следующая ошибка "Internal error: no page 4001", т.е в этоге после форматирования должно выглядить так:
LST_START Starting BAT_R001: AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag
LST_START Starting TGE_R001: Internal error: no page 4
LST_START Starting BAT_R001: AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag
LST_START Starting BAT_R001: AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag
Спасибо сказали:
Аватара пользователя
minoru-kun
Сообщения: 621
ОС: Debian GNU/Linux

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение minoru-kun »

Тогда нельзя поподробнее насчет критериев ошибки?
Кстати, вставшая проблема сигнализирует о том, что было бы неплохо отказаться от анализирования логов вообще, и поискать более компактный и рациональный способ решения вашей задачи.
Спасибо сказали:
dmitri22
Сообщения: 7
ОС: Windows, Linux

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение dmitri22 »

minoru-kun писал(а):
23.04.2008 18:33
Тогда нельзя поподробнее насчет критериев ошибки?

Все строки "LST_START Starting*" это процессы которые запускаются, а ниже этих процессов показываются ошибки, например, "Internal error: no page 4" или "AP_TDS - Tds OCT 20080416 1 032353 not found in tds_get_flag", т.е. получается все что не "LST_START Starting*" является ошибкой. Может этот log (пример) будет понятней:

Starting Process_A001
Starting Process_A006
Starting Process_A007
error 1
error 2
Starting Process_B002
Starting Process_B004
Starting Process_A001
error 1
Starting Process_A006
Starting Process_A007
Starting Process_B002
error 2
Starting Process_B004

задача: вывести все "Process" с ошибками "error", должно быть так:
Process_A007: error 1
Process_A007: error 2
Process_A001: error 1
Process_B002: error 2
Другие Process без ошибок не выводятся.
Спасибо сказали:
Аватара пользователя
minoru-kun
Сообщения: 621
ОС: Debian GNU/Linux

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение minoru-kun »

[offopic]У вас дедлайн на работе, если не секрет? %)[offtopic]
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5456
ОС: Gentoo

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение /dev/random »

Обнаружил проблему, проявляющуюся, если в логе есть пустые строки. Возможно, это именно тот случай. Исправление:
sed -e '/^$/D;1!s/.*LST_START/\n\0/;$s/$/\n/' | sed -e ':a;/\n$/{s/\n/; /g;/.\{32\}/p;D};N;ba'
Спасибо сказали:
dmitri22
Сообщения: 7
ОС: Windows, Linux

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение dmitri22 »

minoru-kun писал(а):
23.04.2008 18:49
[offopic]У вас дедлайн на работе, если не секрет? %)[offtopic]

Да нет, время еще есть :drunk:
Спасибо сказали:
dmitri22
Сообщения: 7
ОС: Windows, Linux

Re: Скрипт обработки текста в shell работает медлено, нужно улучшение алгоритма

Сообщение dmitri22 »

Всем спасибо, пока оставлю свой скрипт но придется осваивать perl для увеличения скорости. Кстати этот скрипт на обычном компьютере работает у меня 10-15 мин, а на сервере его запустил 1 мин, так что пока такой результат пойдет, но все равно нужно увеличить скорость.
Спасибо сказали: