The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"обработка строк"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"обработка строк"  
Сообщение от nastr email(ok) on 24-Фев-09, 17:52 
Есть файл из которого я выбераю строчки содержащие "error#:"
$ grep error#: CHRIS_02240805.txt

Получаю примерно следующие строки:
1561:1235381269590|E|VBJ ThreadPool Worker|sxfw.cmpt.dac.DacSelector|x2chris|*LocalHost|904108025|4|class at.siemens.servicexpress.sxfw.cmpt.dac.DacException message="DacException: error#:904,108,025 >SXFW ,OTHER_ERROR:SQL_EXCEPTION<"
1558:1235333423256|E|VBJ ThreadPool Worker|cx.cmpt.history.HistoryImpl|x2chris|*LocalHost|510102002|2|class at.siemens.servicexpress.cx.cmpt.history.HistoryException message="HistoryException: error#:510,102,002 >database error occured<"

1) теперь нужно вырезать часть строки до первого двоеточия (:)
sed 's/.*:\(.*\)$/\1/g' - не подходит, так как удаляется часть строки не до первого а до последнего двоеточия.
gawk -F":" '{print substr($2,10)}' - не подходит, так как удаляются символы не с окончания строки, а с начала.

2) нужно напечатать первые 10 символов строки получанной после предыдущего преобразования,
перерыл кучу манов, честно говоря не пойму как это сделать..
дальше нужно эти 10 символов преобразовать в нормальную дату:
date "+%Y.%m.%d|%H:%M:%S|" -d@1235333423

3) теперь нужно удалить часть строки после этих первых 10 символов (даты) до слова "error#: " включительно.
???

То есть результетом работы лоджно быть:
2009.02.23|11:27:49|904,108,025 >SXFW ,OTHER_ERROR:SQL_EXCEPTION<"
2009.02.22|22:10:23|510,102,002 >database error occured<"

Буду очень благодарен за помощь!!!

Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "обработка строк"  
Сообщение от angra (ok) on 24-Фев-09, 18:22 
Не будем возится с хлопушками и возьмем в руки настоящее оружие сисадмина - perl
perl -M'POSIX qw(strftime)' -ne 'if (/^\d+:(\d{10,10}).*error#:(.+)/){print strftime("%Y.%m.%d|%H:%M:%S|",localtime $1)."$2\n"}'
Кормить либо с stdin либо список файлов в командной строке. Заметьте, что perl вызывается один раз за все время, а не на каждую строку, что существенно сокращает время обработки больших файлов по сравнению с grep/sed/awk/date/итд

P.S. Если заинтересует как работает данное заклинание могу расписать подробней :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "обработка строк"  
Сообщение от vic (??) on 24-Фев-09, 19:20 
[хлопушко]

awk '{ if (index($0, "error#:")) print strftime("%Y.%m.%d|%H:%M:%S|",substr($0,index($0,":")+1,10)) substr($0,index($0,"error#:")+7) }' < CHRIS_02240805.txt

[/хлопушко]
:)
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "обработка строк"  
Сообщение от angra (ok) on 24-Фев-09, 19:54 
Таки хлопушка  :)
awk: line 2: function strftime never defined

$ awk -W version
mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "обработка строк"  
Сообщение от vic (??) on 24-Фев-09, 21:45 
>Таки хлопушка  :)
>awk: line 2: function strftime never defined
>
>$ awk -W version
>mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan

Аха, код для gawk, и поэтому perl тоже лучше. Однако остальные утилиты можно использовать без излишней конвейеризации и лишних вызов других утилит, если захотеть :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "обработка строк"  
Сообщение от nastr email(ok) on 25-Фев-09, 11:33 
>[хлопушко]
>
 
>awk '{ if (index($0, "error#:")) print strftime("%Y.%m.%d|%H:%M:%S|",substr($0,index($0,":")+1,10)) substr($0,index($0,"error#:")+7) }' < CHRIS_02240805.txt
>

>[/хлопушко]

Огромное спасибо за помощь, это именно то что я хотел сделать!
Теперь отсортировываю по третьему полю и удаляю повторяющиеся:
awk '{ if (index($0, "error#:")) print strftime("%Y.%m.%d|%H:%M:%S|",substr($0,index($0,":")+1,10)) substr($0,index($0,"error#:")+7) }' < CHRIS_02250805.txt | sort -bru +2

Теперь остался ещё один небольшой вопросик.
Учитывая специфику обрабатываемых файлов, в начале строки не всегда может быть количество секунд с 1970 г., тогда в результате обработки получаются следующие строки:
1970.01.01|02:33:29|510,102,002 >database error occured<"
1970.01.01|02:00:00|904,108,025 >SXFW ,OTHER_ERROR:SQL_EXCEPTION<"
Хочу в таких строках заменить первые два поля нолями, думал так:
| awk -F"|" '{if ($1 == "1970.01.01") {$1="0000.00.00"; print}}'
но так заменяются все поля, а не только те которые начинаются на "1970.01.01".
Подскажите пожалуйста как правильно это сделать!


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "обработка строк"  
Сообщение от vic (??) on 25-Фев-09, 12:05 
>Теперь остался ещё один небольшой вопросик.
>Учитывая специфику обрабатываемых файлов, в начале строки не всегда может быть количество
>секунд с 1970 г., тогда в результате обработки получаются следующие строки:

ну я хз что за формат вашего файла, но дальнейший рост условий обработки подсказывает что пора смотреть в сторону perl :)

>1970.01.01|02:33:29|510,102,002 >database error occured<"
>1970.01.01|02:00:00|904,108,025 >SXFW ,OTHER_ERROR:SQL_EXCEPTION<"
>Хочу в таких строках заменить первые два поля нолями, думал так:
>| awk -F"|" '{if ($1 == "1970.01.01") {$1="0000.00.00"; print}}'

а зачем вы пытаетесь делать это после, почему не в момент преобразования в первом скрипте?

awk '{
i = index($0, "error#:");
if (i)
{
    tim = strftime("%Y.%m.%d|%H:%M:%S|", substr($0,index($0,":")+1, 10));
    if (index(tim, "1970.01.01|")) tim="0000.00.00|00.00.00|";
    print tim substr($0,i+7)
}
}' < CHRIS_02250805.txt | sort -bru +2
причем еще лучше было бы анализировать не результат strftime(), а исходное значение поля.
т.к. либо чего-то не знаем или неверно преобразуем хитрообрезанный таймстамп.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "обработка строк"  
Сообщение от nastr email(ok) on 25-Фев-09, 18:02 
>awk '{
>i = index($0, "error#:");
>if (i)
>{
>    tim = strftime("%Y.%m.%d|%H:%M:%S|", substr($0,index($0,":")+1, 10));
>    if (index(tim, "1970.01.01|")) tim="0000.00.00|00.00.00|";
>    print tim substr($0,i+7)
>}
>}' < CHRIS_02250805.txt | sort -ut\| +2

Спасибо, Ваш скрипт просто то что нужно!!

Но теперь обнаружил ещё кое что. В исходном файле достаточно не структурированная информация, из неё можно выделить строки с:
Юниксовским форматом (секунды с 1970 г.),
нормальным форматом даты
просто бессмысленным текстом (без информации о дате).

$ awk '{ if (index($0, "error#:")) print substr($0,index($0,":")+1,19) "| " substr($0,index($0,"error#:")+7) }' CHRIS_02240805.txt | sort -ut\| +2
SxINPluginException| 994,301,001 >SXFW ,USERError
1234984959559|E|VBJ| 510,102,002 >database error occured<"
1235224852014|E|VBJ| 510,102,005 >Inconsistency in database:
1234984959543|E|VBJ| 904,108,025 >SXFW ,OTHER_ERROR:SQL_EXCEPTION<"
2009.02.24_05:52:13| 904,111,055 >SXFW ,CORBA EXCEPTION:Error

Теперь хочу сделать проверку, к примеру:
если строка начинается с "123"
то выполнить
strftime("%Y.%m.%d|%H:%M:%S| ", substr($0,index($0,":")+1, 10));
в противном случае выполнить
print substr($0,index($0,":")+1,19)

Но пока не могу разобраться как это выполнить на awk.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "обработка строк"  
Сообщение от Аноним (??) on 25-Фев-09, 19:00 
>Но теперь обнаружил ещё кое что. В исходном файле достаточно не структурированная
>информация, из неё можно выделить строки с:
>Юниксовским форматом (секунды с 1970 г.),
>нормальным форматом даты
>просто бессмысленным текстом (без информации о дате).

судя по всему у вас нет спеки на формат файла.

используйте функцию match() для определения, что у вас в определенном поле, и соответственно делайте преобразование. match() с регэкспами, а они тут лучше чем сравнение на "123", так же вам надо понять более точно что у вас в третьем варианте "просто бессмысленным текстом" не программируемо)
ну и тупо
>[оверквотинг удален]
>2009.02.24_05:52:13| 904,111,055 >SXFW ,CORBA EXCEPTION:Error
>
>Теперь хочу сделать проверку, к примеру:
>если строка начинается с "123"
>то выполнить
>strftime("%Y.%m.%d|%H:%M:%S| ", substr($0,index($0,":")+1, 10));
>в противном случае выполнить
>print substr($0,index($0,":")+1,19)
>
>Но пока не могу разобраться как это выполнить на awk.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

10. "обработка строк"  
Сообщение от Аноним (??) on 25-Фев-09, 19:02 

>судя по всему у вас нет спеки на формат файла.
>
>используйте функцию match() для определения, что у вас в определенном поле, и
>соответственно делайте преобразование. match() с регэкспами, а они тут лучше чем
>сравнение на "123", так же вам надо понять более точно что
>у вас в третьем варианте "просто бессмысленным текстом" не программируемо)
>ну и тупо

черт, энтер нажал раньше времени))
ну и тупо юзайте if else конструкцию, еще gsub/gensub функции посмотрите

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

11. "обработка строк"  
Сообщение от nastr email(ok) on 26-Фев-09, 13:43 
Спасибо большое за помощь!
Вот последний вариант (по крайней мере пока что:)) того что мне было нужно:

awk '{
i = index($0, "error#:");
a = index($0, "Error <");
if (a) {
    print substr($0,index($0,":")+1,19) "| " substr($0,index($0,"Error <")+7)
}    
if (i) {
    var = substr($0,index($0,":")+1);
    if (match(var, 123)) {
        tim = strftime("%Y.%m.%d_%H:%M:%S| ", substr(var, 0, 10));
        print tim substr($0,i+7)
        }
    else {
        tmp = substr(var, 0, 19);
        if (match(tmp, 200)) {
        print tmp "| " substr($0,i+7)
        }
        else {
        tmp="    .  .  _  .  .  | ";
        print tmp substr($0,i+7)
        }
    }
}
}' < $arg | sort -t\| +1 >> $err


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "обработка строк"  
Сообщение от phpcoder email(??) on 25-Фев-09, 12:05 
>1970.01.01|02:33:29|510,102,002 >database error occured<"
>1970.01.01|02:00:00|904,108,025 >SXFW ,OTHER_ERROR:SQL_EXCEPTION<"
>Хочу в таких строках заменить первые два поля нолями, думал так:
>| awk -F"|" '{if ($1 == "1970.01.01") {$1="0000.00.00"; print}}'
>но так заменяются все поля, а не только те которые начинаются на
>"1970.01.01".

Попробуйте | sed 's|^1970\.01\.01|0000.00.00|'

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру