![]() |
Помогите наваять скрипт? Поиск строки в файле.
Есть файл dns.txt вида
c1601.f1_r1_1.m IN A 10.30.4.61 c1601.f1_r1_1_s1.m IN A 10.30.4.61 c1601.kf1_r1_1_s0.m IN A 10.30.4.78 c2811.f1-r1_1.m IN A 10.30.40.1 c2811.f1-r1_1_vl2.m IN A 10.30.40.1 c2811.f1-r1_1_s0-0-0_1.m IN A 10.30.40.10 c7206.f2-r206_1_vl15.m IN A 10.30.40.101 zy782.hd_f2-r1_1_dsl.m IN A 10.30.40.102 zy791.h3_f1-r1_1.m IN A 10.30.40.105 zy791.h3_f1-r1_1_lan.m IN A 10.30.40.105 порядка 6000 строк. Нужно в нем в цикле смотреть строку 10.30.0-255.0-255 и если ее нет, то добавлять в конец файла сформированную строку "ИмяУстройства IN A ИПАдрес", строку я знаю как формировать. Прошу помощи. И еще самый главный вопрос - когда я формирую это файл - он генерится около 12 часов (пинг по IP с таймаутом 1 сек, если есть пинг, то опрос по SNMP), так вот - не увеличит ли поиск такого каждого IP в этом файле время работы скрипта в геометрической прогрессии? Сумбурно написал... |
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
|
glukin, Сумбурно написал... таки да! Опрашивайте Вашу сеть, пишите результаты в новый файл, например, dns.txt.tmp, после завершения опроса запустите процесс анализа dns.txt на основе dns.txt.tmp, делая необходимые дополнения. А затем я бы еще отсортировал dns.tmp например по IP. Порядок освобождает мысль.
Или, еще лучше, прежде чем пинговать, поищите IP в dns.tmp, и, если он есть, не пингуйте - Вы уже это ранее сделали, зачем делать заново? А то , что пропингуете, запишите в dns.txt.tmp и по окончании, объедините инфу из обоих файлов. |
Вложений: 1
Iska,
1. Файл вложил, пароль в личке. PS^ Вам не отправляется личка, пишет: Iska превысил(а) максимальный объем сохраненных персональных сообщений и не может получать новые сообщения, пока не удалит часть старых. 2. Напишу как умею - на С: for(i=0;i<256;i++) for(j=0;j<256;j++) {Тело цикла;} 3. Строка - IP-адрес, формируемый из 10.30 + i + j. 4. Да. 5. Не последовательно - это как? Мне нужно, чтобы весь диапазон был опрошен. 6. Необязательно, можно те IP, которых нет, добавить в отдельный файл, потом этот файл соединить с исходным. |
Цитата:
Думаю, может, сделать по-другому? Я 1 раз сформирую эталонный файл dns.txt, затем по расписанию пинговать всю сеть на предмет появления новых устройств, формировать новый файл dns.txt.tmp и сравнивать 2 файла. Разницу в файлах дописывать в конец эталона, вот так вроде правильно написал. "А затем я бы еще отсортировал dns.tmp например по IP." Они и так будут по IP, dns.tmp пишется в цикле же i=0-255;j=0-255. А можно как-либо сравнить 2 файла, чтобы выделить неприсутствующие во втором файле строки в отдельный файл (с ними потом еще работать другому скрипту) и дописать их в первый файл? |
Вероятно, задача нерешаема без административных методов. Не могу сообразить, что делать, если устройство выведено из эксплуатации и не пингуется, но в эталонном dns.txt оно есть. И еще - их периодически выключают, то есть они могут быть в эксплуатации, но не пинговаться. (((
|
glukin, чтобы выделить не присутствующие во втором файле строки в отдельный файл надо сформировать IP-адрес, поискать его в dns.txt, если его нет - пингуем и пишем в файл dns.txt.tmp - я эту идею уже излагал.
Если устройство выведено из эксплуатации и не пингуется, удалить его из эталонного файла можно только ручками, так как имеются другие устройства в эксплуатации, но не пингуются, так как выключены. Можно, конечно, перепинговать все имеющиеся в dns.txt устройства, имеющиеся непингуемые записать в отдельный файл, затем опять же глазками его проанализировать. Наверное, стоит разделить эти задачи: поиск новых и анализ непингуемых. Вероятно, задача нерешаема без административных методов - на каждый объект должен быть паспорт, нас по требованиям безопасности заставили это сделать. Там отображаются все изменения объекта, от ввода в эксплуатацию, изменения конфигурации и софта, до его утилизации. А сортировать данные после объединения 2 файлов всё равно придётся, так как Вы собираетесь добавлять в конец файла новые сформированные строки, которые уже выпадают из предыдущего порядка следования. А для меня пароль недоступен? Боитесь, что контрагайку откручу? :) |
1. Это сделать я могу.
2. Так я и затеял все это, чтобы не делать ручками. Устройства выключают только на ночь и на выходные, так что можно успеть, но проблема в том, что скрипт работает очень долго (порядка 15 часов), можно и не успеть. А с учетом анализа dns.txt боюсь, что время увеличится в разы. 3. Да, пожалуй. 4. Это все есть, но неудобно, слишком все распределено территориально и слишком много админов. 5. А для чего вообще его сортировать? 6. Пароль выслал. |
glukin, к сожалению, цели и задачи я не смог уяснить толком. Посему, могу лишь дать наводку на улучшение той части, которую понял.
Асинхронные запросы Wbem: vbscript: асинхронная обработка множественных запросов WMI — Windows Script Host, HTA (VBScript, JScript) — Коллекция скриптов и идей — Серый форум. Фоновые задания PowerShell, используемый класс .Net — System.Net.NetworkInformation.Ping: Многопоточный сканер сети | PowerShell и другие скрипты (даю ссылку на кэш Google'а, поскольку сайт Василия, видимо, того… Увы :(). Вы, поскольку знаете C/C++, кроме изложенного выше, можете и вовсе банально использовать в своём приложении несколько потоков. Кроме того, Вы можете писать не в текстовый файл, а в базу данных — Jet или SQL (если есть), в последующем работать с базой данных будет многим проще (фильтрация, запросы и т.п.), нежели с банальным текстовым файлом. В частности, задача: Цитата:
|
Цель - актуализировать прямую и обратную зоны DNS для DNS-сервера устройств СПД, так, чтобы там не было выведенных из эксплуатации устройств, и , наоборот, не вводить вновь введенные в эксплуатацию устройства туда руками, как это делается сейчас.
"Асинхронные запросы Wbem" О! Вот это полезная штука, спасибо большое! Потестю на предмет скорости, если будет быстрее хотя бы раза в 2, чем сейчас - решится проблема выключенных устройств, находящихся в эксплуатации. PowerShell не подходит, так как сервер, где будет работать скрипт - Win2003, и переехать на другой нет возможности, так как только с него разрешен SNMP на устройства СПД. Я понимаю, что с БД будет работать быстрее, и , возможно, проще, но БД я не умею от слова "вообще". |
Цитата:
Цитата:
Windows Management Framework (Windows PowerShell 2.0, WinRM 2.0, and BITS 4.0) Download Update for Windows Server 2003 (KB968930) from Official Microsoft Download Center Цитата:
|
Спасибо! Пока попробую асинхронный опрос, по результату отпишусь.
|
del
|
Iska, Все отлично! Прирост в скорости примерно в 20 раз. То, что нужно!!
Проблема обнаружилась другая - почему-то не все устройства отдают свой SNMP sysName при абсолютно одинаковых настройках, но это вопрос, наверное, не сюда. Буду допиливать дальше... |
Поясните, пожалуйста, почему не работает конструкция вида:
'============================================================================= ' Процедура асинхронной обработки экземпляра объекта (замечание: в данном конкретном случае ' будет возвращаться единственный объект, однако, в большинстве случаев запросы ' возвращают множество объектов) Sub Sink_OnObjectReady(objWbemObject, objWbemAsyncContext) Dim strComputer strComputer = objWbemAsyncContext.Item("HostName") If Not IsNull(objWbemObject.StatusCode) Then If objWbemObject.StatusCode = 0 Then objWmiNamedValueSet.Add "AgentAddress", strComputer objWmiNamedValueSet.Add "AgentReadCommunityName", "poll" 'on error resume next Set colSystem = objWmiServices.InstancesOf("SNMP_RFC1213_MIB_system", , objWmiNamedValueSet) WSCript.Echo IsNull(objSystem) If Not IsNull(colSystem) Then For Each objSystem In colSystem If (Right(objSystem.sysName,12)="123") Then objSystem.sysName=Left(objSystem.sysName,Len(objSystem.sysName)-12) + ".m" Else objSystem.sysName=objSystem.sysName + ".m" End If NFile1.WriteLine objSystem.sysName + " IN A " + strComputer Next Else objWmiNamedValueSet.Add "AgentReadCommunityName", "public" Set colSystem = objWmiServices.InstancesOf("SNMP_RFC1213_MIB_system", , objWmiNamedValueSet) If Not IsNull(colSystem) Then For Each objSystem In colSystem If (Right(objSystem.sysName,12)="123") Then objSystem.sysName=Left(objSystem.sysName,Len(objSystem.sysName)-12) + ".m" Else objSystem.sysName=objSystem.sysName + ".m" End If NFile1.WriteLine objSystem.sysName + " IN A " + strComputer Next Else NoSNMP.WriteLine strComputer End If End If End If End If End Sub Выдаёт ошибку null на "For Each objSystem In colSystem" |
|
Iska, Без изменений.
ПС: на устройствах, которые отдают SNMP sysName все работает, не работает только на тех, которые SNMP не умеют. |
Тогда детализируйте (ибо гадать не интересно) — на каком из двух:
Цитата:
|
Iska, На первом.
--------------------------- Windows Script Host --------------------------- Script: C:\Documents and Settings\Administrator\Desktop\ping.vbs Line: 117 Char: 5 Error: 0x80041010 Code: 80041010 Source: (null) --------------------------- OK --------------------------- ПС: Я понимаю, что при скане ИП-адресов какой-то из ИП выдает NULL, то есть или не умеет SNMP, или access denied, но почему этот NULL не обрабатывается If'ами? |
Ну, это ведь совсем не «null». Судя по описанию, Вы пытаетесь использовать несуществующий класс в указанном пространстве Wbem.
Попробуйте сделать проверку существования класса, наподобие: Код:
Option Explicit |
Iska, Боюсь, что для меня это крутовато, не осилил. Пожалуй сделаю как-то так:
on error resume next затем если (пинг прошел)&(была запись в файл) то NoSNMP=False иначе NoSnmp=True если NoSNMP то пишем в файл ИП-адрес "плохого" устройства Только пока не разобрался с переходами по on error resume next Трудно без нормального отладчика с контрольными точками и пошаговым выполнением команд ((( Покритикуйте алгоритм. |
Прошу помощи в реализации на vbs.
|
Покажите Ваш текущий код (не забывайте обрамлять его тэгом «code»).
|
Iska, Вот
Код:
'============================================================================= Другими словами - прошел пинг и прошла запись "NFile1.WriteLine objSystem.sysName + " IN A " + strComputer" то оно умеет, иначе пишем его ИП-адрес в файл для дальнейшего анализа. |
glukin, это только одна процедура. Я имел в виду — весь код.
|
Iska, ок
Код:
File_Out1 = "D:\SNMP.txt" |
Тяжёлый код. Используйте Option Explicit в начале кода, препятствует появлению многих глупых ошибок с описками в именовании переменных.
Попробуйте так (добавить всё ту же функцию): Код:
Function ClassExists(objSWbemServicesEx, strClassName) Код:
Sub Sink_OnObjectReady(objWbemObject, objWbemAsyncContext) |
Iska, ОК, спасиб, завтра буду пробовать.
А еще, не подскажете, как мне из строки вида "10.31.101.102" сформировать строку вида "102.101" в этой же функции после строки "NFile1.WriteLine objSystem.sysName + " IN A " + strComputer " ? Ну то есть, брать 2 последних октета из strComputer и их поменять местами? А то как не пробую - у меня все type mismatch вылезает. Да, я понял, что так писать нельзя (без обявления переменных), но с нуля сложно пока для меня за всеми переменными уследить, да еще и без отладчика, в блокноте. ((( |
Цитата:
Быстро
Код:
WScript.Echo Split("10.31.101.102", ".")(3) & "." & Split("10.31.101.102", ".")(2) По-научному
Код:
Option Explicit Цитата:
Цитата:
Скрытый текст
![]() Скрытый текст
![]() Я ж Вам писал: Цитата:
|
Iska, Я так понимаю, что это будет работать, только если "101.102", а если "1.2"? То есть октеты не обязательно будут в 3 символа.
В Фаре не нашел такой функциональности, VBSEdit хорош, но пошаговой отладки тоже там не нашел. Да и платить не хочется. ))) |
Цитата:
Цитата:
Цитата:
Скрытый текст
![]() В принципе, можно пользовать Microsoft Script Debugger. При наличии Microsoft Office, использовать тамошний отладчик из редактора Microsoft Script Editor, но, повторюсь: для меня самый быстрый способ — редактор и консоль Far Manager'а. |
Iska, добрый день, наконец-то у меня дошли руки до скрипта.
Вы писали: "Попробуйте так (добавить всё ту же функцию):" Все равно не работает, выдает ошибку, когда натыкается на устройство без SNMP - тот же (null) --------------------------- Windows Script Host --------------------------- Script: C:\Documents and Settings\rp\Desktop\ping1.vbs Line: 120 Char: 12 Error: 0x80041010 Code: 80041010 Source: (null) --------------------------- OK --------------------------- Вот код процедуры, что я делаю не так? Код:
Sub Sink_OnObjectReady(objWbemObject, objWbemAsyncContext) Спасибо. Добавил отладки, в жирную ветку функции, которую Вы посоветовали, не попадает. (( Код:
Function ClassExists(objSWbemServicesEx, strClassName) |
glukin, такое ощущение, что класс есть, а экземпляров класса нет. Попробуйте всё-таки вместо прямого обращения к коллекции по .InstancesOf("SNMP_RFC1213_MIB_system"…) сделать запрос посредством .ExecQuery("SELECT * FROM SNMP_RFC1213_MIB_system"…).
Мне, к сожалению, банально даже не на чем проверить. |
Iska, Ничего не понимаю.
Попробовал дома на устройствах, которые точно не умеют SNMP - все работает! Дома Win7 Ultimate, где ошибка - Win2003, может, дело в версиях винды и 2003-я винда не умеет, то что Вы написали? Только проблема в том, что дома наоборот - нет того, кто бы умел SNMP, полностью работу не проверишь. )) |
Iska, Добавлю: убрал проверку на ClassExists, ошибка вылетает такая же, то есть в Win2003 не работает функция ClassExists, а в Win7 она работает.
Проверить можно на локалхосте (127.0.0.0-255). Help! |
Iska, "glukin, такое ощущение, что класс есть, а экземпляров класса нет. Попробуйте всё-таки вместо прямого обращения к коллекции по .InstancesOf("SNMP_RFC1213_MIB_system"…) сделать запрос посредством .ExecQuery("SELECT * FROM SNMP_RFC1213_MIB_system"…)."
Все то же самое... --------------------------- Windows Script Host --------------------------- Script: C:\Documents and Settings\rp\Desktop\ping1.vbs Line: 121 Char: 12 Error: 0x80041010 Code: 80041010 Source: (null) --------------------------- OK --------------------------- На той же строке. |
glukin, что мне потребуется для того, чтобы проверить у себя работу Вашего скрипта?
|
Iska, сделал через If Error Resume Next, так что думаю на этом и остановиться.
Спасибо. |
Iska, впрочем, если есть желание и время, можете попробовать, вот код для локалхоста, но нужен или win2003 server или winXP. Ибо на 7-ке все работает.
Скрытый текст
Код:
File_Out1 = "C:\SNMP.txt" |
Время: 17:21. |
Время: 17:21.
© OSzone.net 2001-