|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - Парсинг XML/TXT |
|
|
CMD/BAT - Парсинг XML/TXT
|
Пользователь Сообщения: 69 |
Доброго всем времени суток, опять обращаюсь за помощью )
Суть такова, имеется xml-файл (мноооооого строк), ну даже наверное точнее будет сказать txt, ибо как тэги там непонятные, в некоторых строках содержатся такие записи - NUM="1234567890" и MAIL="mail@mail.ru" соответственно в одной строке номеру соответствует мыльник, кое-где мыльников нет Нужно извлечь в другой файл номера и адреса, т.е. 1234567890 mail@mail.ru 0987654321 mail2@mail.ru .... Возможно ли? Заранее спасибо! |
|
Отправлено: 14:12, 16-07-2012 |
Ветеран Сообщения: 27449
|
Профиль | Отправить PM | Цитировать Цитата mxm199:
|
|
Отправлено: 17:19, 16-07-2012 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Старожил Сообщения: 415
|
Профиль | Отправить PM | Цитировать Вариант с использованием grep. Он основан на регулярных выражениях, поэтому универсален и не зависит от тэгов XML или чего-то ещё. Главное для составления пары "телефон-email" это то, чтобы они оба находились на одной строке.
Распознаваемые форматы номеров: 123-456-7890 (123)456-7890 123 456 7890 1234567890 Файл, на котором проверялась работа скрипта: NUM="1234567890" MAIL="mail@mail.ru" NUM="0987654321" MAIL="test@test.test.com" NUM="0851236214" 0987654320 NUM="3333333333" MAIL="12345_67890@gmail.com" MAIL="abuse@hetzner.de" admin@test.com NUM="0000000000" MAIL="000@ya.ru" support@leaseweb.com (111)2223334 @Echo Off Set Path=%Path%;%CD%\bin Set XMLFile=file.txt :: Получаем адреса почты с помощью регулярного выражения, обязательно проверяем :: номер строки для составления пар. Последний номер строки пишется во временную :: переменную, нужную для дальнейшей работы цикла, выдающего данные в два столбца. For /F "tokens=1,* delims=:" %%A In ('grep -Eiorhn "([[:alnum:]_.-]+@[[:alnum:]_.-]+?\.[[:alpha:].]{2,6})" "%XMLFile%"') Do ( Set EMail_%%A=%%B Set EMails=%%A ) :: Проделываем то же самое с телефонами. For /F "tokens=1,* delims=:" %%A In ('grep -oin "\(([0-9]\{3\})\|[0-9]\{3\}\)[ -]\?[0-9]\{3\}[ -]\?[0-9]\{4\}" "%XMLFile%"') Do ( Set Phone_%%A=%%B Set Phones=%%A ) :: Определяем максимальное число результатов для работы For /L. If %EMails% GEQ %Phones% (Set Matches=%EMails%) Else (Set Matches=%Phones%) SetLocal EnableDelayedExpansion :: Добавляем один таб к не пустым значениям и два - к пустым. Отсекаем оба :: пустых через grep -v. Это обеспечивает ровную таблицу, даже если число :: телефонов и ящиков непарное, либо в строке указан лишь один из них. Set i=0 For /L %%A In (1,1,%Matches%) Do ( If Defined Phone_%%A (Set Phone_%%A=!Phone_%%A! ) Else (Set Phone_%%A= ) If Defined EMail_%%A (Set EMail_%%A=!EMail_%%A! ) Else (Set EMail_%%A= ) :: Считаем проценты выполнения, свистоперделка, но пусть будет Set /A i+=1 Set /A Progress=i*100/%Matches%||Set Progress= 0 If !Progress! LSS 10 ( Set Progress= !Progress! ) Else ( If !Progress! LSS 100 Set Progress= !Progress! ) Echo !Progress!%% !Phone_%%A!!EMail_%%A!|grep -vi "(ECHO)" :: Выводим те же данные в файл Echo !Phone_%%A!!EMail_%%A!|grep -vi "(ECHO)">>out.txt ) Pause&Exit |
Последний раз редактировалось Anonymоus, 17-07-2012 в 00:18. Причина: Добавлен счетчик обработки файла в процентах Отправлено: 00:01, 17-07-2012 | #3 |
Пользователь Сообщения: 69
|
Профиль | Отправить PM | Цитировать .....честно говоря слов нет. Профессионально. СПАСИБО!
Только вопрос нарисовался ) Если регулярку по номерам обрезать только до поиска 1234567890 (номера только такого формата, это не телефоны а уникальные номера) скорость поиска увеличится? Можно ли разделить не табами а ";" ? И на Вашем файле тестовом отлично отработал, а на моём в ~6000 тыс. строк, тоже всё нашёл, но сам не завершился, стал крутить до бесконечности, выдавая - "Неверное число. Числа ограничены 32 битами чётности. 0%" (точнее это выдавать он начал сразу, но отбирал данные) пока сам не прервал процесс. (это судя по-всему из-за процентов выполнения), но и с отключенным этим блоком, всё равно, не завершает процесс |
Отправлено: 09:52, 17-07-2012 | #4 |
Старожил Сообщения: 415
|
Профиль | Отправить PM | Цитировать mxm199, нет, повышения быстродействия не будет, т.к. grep отрабатывает всю регулярку целиком за один запуск. Если бы я каждый раз на определённый шаблон номера запускал по процессу grep'а, тогда стоило бы оптимизировать.
Сколько строк в файле? Попробуйте вот это, тут убрано всё лишнее и разделитель изменён на точку с запятой. Кроме того, быстродействие повышено из-за фильтрации пустых строк через If, а не grep, как в прошлом варианте. @Echo Off Set Path=%Path%;%CD%\bin Set XMLFile=file.txt For /F "tokens=1,* delims=:" %%A In ('grep -Eiorhn "([[:alnum:]_.-]+@[[:alnum:]_.-]+?\.[[:alpha:].]{2,6})" "%XMLFile%"') Do (Set EMail_%%A=%%B&Set EMails=%%A) For /F "tokens=1,* delims=:" %%A In ('grep -oin "\(([0-9]\{3\})\|[0-9]\{3\}\)[ -]\?[0-9]\{3\}[ -]\?[0-9]\{4\}" "%XMLFile%"') Do (Set Phone_%%A=%%B&Set Phones=%%A) If %EMails% GEQ %Phones% (Set Matches=%EMails%) Else (Set Matches=%Phones%) SetLocal EnableDelayedExpansion For /L %%A In (1,1,%Matches%) Do ( Set Out=!Phone_%%A!;!EMail_%%A! If Not "!Out!"==";" Echo !Out!>>"out.txt" ) Pause&Exit |
|
Последний раз редактировалось Anonymоus, 17-07-2012 в 10:22. Отправлено: 10:15, 17-07-2012 | #5 |
Пользователь Сообщения: 69
|
Профиль | Отправить PM | Цитировать строк изначально было порядка 6000, но я обрезал до 20, смысл тот же остался (на старом варианте)
на этом тоже самое, т.е. Ваш тестовый отлично отрабатывает и выходит, на моём файле ни в какую, тоже отрабатывает, всю информацию выбирает, но закрываться не хочет, только контрол-с помогает... п.с. и всё-таки с табами оказалось лучше, извиняюсь ) |
Отправлено: 10:55, 17-07-2012 | #6 |
Старожил Сообщения: 415
|
Профиль | Отправить PM | Цитировать Пример файла можно?
|
Отправлено: 11:02, 17-07-2012 | #7 |
Пользователь Сообщения: 69
|
Профиль | Отправить PM | Цитировать Послал в личку
|
Отправлено: 11:34, 17-07-2012 | #8 |
Старожил Сообщения: 415
|
Профиль | Отправить PM | Цитировать mxm199, убрал универсальные регэкспы, заточил под тот формат файла, что вы мне дали.
@Echo Off SetLocal EnableDelayedExpansion Set Path=%Path%;%CD%\bin Set XMLFile=file.txt For /F "tokens=1,3 delims==:" %%A In ('grep -ion "EMAIL=.[^ =]*." "%XMLFile%"') Do ( Set EMail=%%B&Set EMail=!EMail:"=! Set EMail_%%A=!EMail! Set EMails=%%A ) For /F "tokens=1,3 delims==:" %%A In ('grep -ion "PHONE=.[^ =]*." "%XMLFile%"') Do ( Set Phone=%%B&Set Phone=!Phone:"=! Set Phone_%%A=!Phone! Set Phones=%%A ) If %EMails% GEQ %Phones% (Set Matches=%EMails%) Else (Set Matches=%Phones%) For /L %%A In (1,1,%Matches%) Do ( Set Out=!Phone_%%A! !EMail_%%A! If Not "!Out!"==" " Echo !Out! ) Pause&Exit |
Отправлено: 12:14, 17-07-2012 | #9 |
Пользователь Сообщения: 69
|
Профиль | Отправить PM | Цитировать ) работает! КРАСОТА! Спасибо!
для вывода в файл добавляю строку Echo !Phone_%%A!!EMail_%%A!|grep -vi "(ECHO)">>out.txt ? |
Отправлено: 12:28, 17-07-2012 | #10 |
|
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Java - Парсинг doc-файла | Hector | Программирование и базы данных | 7 | 15-03-2012 21:37 | |
CMD/BAT - Парсинг | Чин Хон | Скриптовые языки администрирования Windows | 1 | 04-02-2011 13:51 | |
Delphi - Парсинг | Miko | Программирование и базы данных | 7 | 27-09-2010 10:46 | |
Парсинг PR | venuko | Вебмастеру | 3 | 13-01-2010 14:15 | |
C/C++ - [решено] строковой парсинг | Surround | Программирование и базы данных | 2 | 17-03-2008 16:51 |
|