Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   массив из строк, поиск по строке (http://forum.oszone.net/showthread.php?t=327443)

matson 08-06-2017 16:55 2742968

массив из строк, поиск по строке
 
Добрый день.
Пытаюсь решить задачу по парсингу лог-файла с конца самого файла. Получилось поделить лог на строки и строки положить в одномерный массив. Вот только как произвести поиск по строке, которая лежит внутри ячейки одномерного массива?

На примере:

вот такой вариант работает (ищет точку входа в строку):
Код:

z = "    2017-06-07 23:01 Пользователь  sadfasdasd qwddsda dqwd sad qwdsad asd"
y = InStr(1, z, "Пользователь")

а вот такой нет (всегда 0):

Код:

z = my_arr(10) ' в данной ячейке лежит строка "    2017-06-07 23:01 Пользователь  sadfasdasd qwddsda dqwd sad qwdsad asd"
y = InStr(1, z, "Пользователь")


nexochyka 08-06-2017 18:15 2742990

Проверь формат ячейки (as string ?). У меня твой пример работает.
Код:

y=InStr(1, my_arr(10), "польз", vbTextCompare)

Iska 08-06-2017 18:40 2743001

Цитата:

Цитата matson
с конца самого файла. »

и:
Цитата:

Цитата matson
положить в одномерный массив »

входят в явное противоречие. Используйте базу данных.

Цитата:

Цитата matson
внутри ячейки одномерного массива? »

У массивов нет ячеек. Есть элементы.

Цитата:

Цитата matson
а вот такой нет (всегда 0): »

Чушь.

Упакуйте образец лог-файла в архив и приложите к сообщению. Опишите задачу.

matson 09-06-2017 11:03 2743122

задача: есть лог от Cobian Backup, необходимо получить данные о успешном/не успешном резервном копировании и количестве ошибок (если есть). Задание может выполняться несколько раз за сутки, следовательно необходима самая последняя запись в txt (поэтому читаем лог снизу вверх). По завершении задачи будет запускаться данный скрипт (средствами Cobian).
нет никакого смысла использовать бд для такой простой задачи, не люблю плодить сущности.
Для вашего "чушь" гифка по ссылке как это работает (точнее как не работает)GIF
msgbox (TypeName(my_arr(9))) говорит что лежит строка


Кусок лога имеет такой вид

Код:

2017-06-07 18:10 --
    2017-06-07 21:00 *** Запущено новое копирование. Заданий в очереди: 1 ***
    2017-06-07 21:00 Отключение возможности входа в спящий режим...
    2017-06-07 21:00 ** Выполнение задания "BackGTD" **
    2017-06-07 21:00 Подсчёт файлов в задании "BackGTD"...
    2017-06-07 21:00 Запуск теневого копирования тома: D:\
    2017-06-07 21:01 Теневая копия создана
    2017-06-07 21:01 Соединение с "192.168.3.8:21"...
    2017-06-07 21:01 TLS недоступен на указанном сервере, попытка обычного соединения...
    2017-06-07 21:01 Пользователь "administrator" начал сеанс связи с "192.168.3.8:21"
    2017-06-07 21:01 Каталог "BackGTD 2017-06-07 21;01;07 (Разностный)" создан
    2017-06-07 21:01 Каталог cменён на "BackGTD 2017-06-07 21;01;07 (Разностный)"
    2017-06-07 21:01 Закачка каталога "GLOBALROOT\Device\HarddiskVolumeShadowCopy11\BackGTD"
    2017-06-07 21:44 Удаление теневой копии "587861c8-ae9a-494f-b00d-428cd458c070"
    2017-06-07 21:44 Теневая копия удалена
    2017-06-07 21:44 Общее время выполнения задания "BackGTD": 0 ч., 44 мин., 11 сек.
    2017-06-07 21:44 ** Задание "BackGTD" завершено. Ошибок: 0, обработано файлов: 45789, скопировано файлов: 5131, общий размер: 25,91 GB **
    2017-06-07 21:44 --
    2017-06-07 21:44 Возможность входа в спящий режим включена
    2017-06-07 21:44 Общее время копирования: 0 ч., 44 мин., 15 сек.
    2017-06-07 21:44 *** Копирование завершено. Ошибок: 0, обработано файлов: 45789, скопировано файлов: 5131, общий размер: 25,91 GB ***
    2017-06-07 21:44 --


вот таким скриптом получаю строки. В 9 элементе массива лежит строка "2017-06-07 23:01 Пользователь....". На количество переменных не обращайте внимания,

Код:

Dim F, i, s, fn, FSO, ForReading, AllTxt, listLines, str, x, arr_Line, my_arr(), y, z, nStrok, SearchString
ForReading = 1
fn = "C:\Users\root\Desktop\log 2017-06-07.txt" '// <-- full path
arr_Line = 0
Set FSO = CreateObject("Scripting.FileSystemObject")
Set F = FSO.OpenTextFile(fn, ForReading, False, -2)
Do Until F.AtEndOfStream ' пока наступит конец файла
                Redim Preserve my_arr(arr_Line)
                my_arr(arr_Line) = F.ReadLine ' Считываем строку
                arr_Line = arr_Line + 1
                nStrok = UBound(my_arr) 
Loop
F.Close

msgbox my_arr(9)
'z = "2017-06-07 23:01 Пользователь  sadfasdasd qwddsda dqwd sad qwdsad asd"
y = InStr(1, my_arr(9), "Польз", vbTextCompare)
msgbox y


greg zakharov 09-06-2017 11:27 2743129

По логу (ровно как и по самой постановке задачи) ничего не понятно: нужно извлекать данные из лога по какому критерию? На какие значения нужно опираться? Зачем каждую строку пихать в массив, чай ведь не экономный расход ресурсов?

matson 09-06-2017 11:39 2743133

Смотрите: в логах ищем строку "Задание "BackGTD" завершено. Ошибок:". При нахождении подстроки в элементе массива (InStr >0) начинаем работать со строкой и получать дату-время, количество ошибок и т.п., а это отправляется на zabbix.
Цитата:

Цитата greg zakharov
Зачем каждую строку пихать в массив, чай ведь не экономный расход ресурсов? »

Если вы подскажете более правильный и красивый вариант, я буду очень признателен. Не нашел пока более правильного варианта поиска данных в строке, если строк с одинаковым текстом может быть несколько (то есть несколько одинаковых строк "Задание "BackGTD" завершено. Ошибок:", только разное количество ошибок)

greg zakharov 09-06-2017 11:51 2743137

Есть такая штука, RegExp называется. Открываете файл на чтение, читаете построчно, и если строкка соответствует шаблону регулярного выражения, извлекаете данные из подгрупп регулярки (дату, количество ошибок, обработанных файлов и дыр и пыр).

matson 09-06-2017 13:35 2743174

Толи лыжи не едут...
пытаюсь сделать проверку на чтении построчно
Код:

Dim F, i, s, fn, FSO, ForReading, AllTxt, listLines, str, x, arr_Line, my_arr(), y, z, nStrok, SearchString
ForReading = 1
fn = "C:\Users\root\Desktop\log 2017-06-07.txt" '// <-- full path
arr_Line = 0
Set FSO = CreateObject("Scripting.FileSystemObject")
Set F = FSO.OpenTextFile(fn, ForReading, False, -2)
SearchString = "Теневая копия создана"

Do Until F.AtEndOfStream ' пока наступит конец файла
                Str = F.ReadLine
                If (InStr(1, Str, SearchString) > 0) Then
                MsgBox Str
                End If
Loop
F.Close

Но тишина! Хотя строчка, содержащая "Теневая копия создана" точно присутствует в файле

matson 09-06-2017 15:13 2743206

дело было не в бобине, дело было в кодировке...

Iska 09-06-2017 19:47 2743271

Цитата:

Цитата matson
дело было не в бобине, дело было в кодировке... »

Вот потому и предлагалось:
Цитата:

Цитата Iska
Упакуйте образец лог-файла в архив и приложите к сообщению. »

а не копировать «кусок лога» в виде текста.

megaloman 09-06-2017 19:55 2743273

matson, Не понимаю, что Вы хотите в конце концов получить, но вот вариант (тестировал на файле, созданном на основе приведенного Вами текста):
Код:

File_In = "Z:\Box_In\Логфайл.log"
Find_String = "** Задание ""BackGTD"" завершено."

Set FSO = CreateObject("Scripting.FileSystemObject")

Set NFile = FSO.OpenTextFile(File_In, 1, False)                    '  Открываем текстовый файл
S = NFile.ReadAll
NFile.Close

MsgBox Last_String(S, Find_String)

Function Last_String(All_S, Find_S)
    i_Find_S = InStrRev(All_S, Find_S)
    If i_Find_S > 0 Then
        NFind_1 = InStrRev(All_S, vbCrLf, i_Find_S)
        NFind_2 = InStr(i_Find_S, All_S, vbCrLf)
        Last_String = LTrim(RTrim(Replace(Mid(All_S, NFind_1, NFind_2 - NFind_1 + 1), vbCrLf, "")))
    Else
        Last_String = ""
    End If
End Function

Не вижу смысла получать массив.

Iska 09-06-2017 21:35 2743305

Цитата:

Цитата matson
нет никакого смысла использовать бд для такой простой задачи, не люблю плодить сущности. »

Пока лог в сотни килобайт — да, возможно. Когда в сотни мегабайт — тогда стоит работать с ним либо как с базой данных, либо задействовать LogParser.


Время: 11:18.

Время: 11:18.
© OSzone.net 2001-