Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - Парсинг XML/TXT

Ответить
Настройки темы
CMD/BAT - Парсинг XML/TXT

Пользователь


Сообщения: 69
Благодарности: 0

Профиль | Отправить PM | Цитировать


Изменения
Автор: mxm199
Дата: 16-07-2012
Доброго всем времени суток, опять обращаюсь за помощью )
Суть такова, имеется xml-файл (мноооооого строк), ну даже наверное точнее будет сказать txt, ибо как тэги там непонятные, в некоторых строках содержатся такие записи -
NUM="1234567890" и MAIL="mail@mail.ru"
соответственно в одной строке номеру соответствует мыльник, кое-где мыльников нет
Нужно извлечь в другой файл номера и адреса, т.е.
1234567890 mail@mail.ru
0987654321 mail2@mail.ru
....
Возможно ли?


Заранее спасибо!

Отправлено: 14:12, 16-07-2012

 

Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


Цитата mxm199:
имеется xml-файл (мноооооого строк) »
Сколько именно?

Отправлено: 17:19, 16-07-2012 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Старожил


Сообщения: 415
Благодарности: 257

Профиль | Отправить 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
Благодарности: 0

Профиль | Отправить PM | Цитировать


.....честно говоря слов нет. Профессионально. СПАСИБО!

Только вопрос нарисовался )
Если регулярку по номерам обрезать только до поиска 1234567890 (номера только такого формата, это не телефоны а уникальные номера) скорость поиска увеличится?

Можно ли разделить не табами а ";" ?

И на Вашем файле тестовом отлично отработал, а на моём в ~6000 тыс. строк, тоже всё нашёл, но сам не завершился, стал крутить до бесконечности, выдавая -
"Неверное число. Числа ограничены 32 битами чётности. 0%" (точнее это выдавать он начал сразу, но отбирал данные)
пока сам не прервал процесс. (это судя по-всему из-за процентов выполнения), но и с отключенным этим блоком, всё равно, не завершает процесс

Отправлено: 09:52, 17-07-2012 | #4


Старожил


Сообщения: 415
Благодарности: 257

Профиль | Отправить 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
Благодарности: 0

Профиль | Отправить PM | Цитировать


строк изначально было порядка 6000, но я обрезал до 20, смысл тот же остался (на старом варианте)
на этом тоже самое, т.е. Ваш тестовый отлично отрабатывает и выходит, на моём файле ни в какую, тоже отрабатывает, всю информацию выбирает, но закрываться не хочет, только контрол-с помогает...

п.с. и всё-таки с табами оказалось лучше, извиняюсь )

Отправлено: 10:55, 17-07-2012 | #6


Старожил


Сообщения: 415
Благодарности: 257

Профиль | Отправить PM | Цитировать


Пример файла можно?

Отправлено: 11:02, 17-07-2012 | #7


Пользователь


Сообщения: 69
Благодарности: 0

Профиль | Отправить PM | Цитировать


Послал в личку

Отправлено: 11:34, 17-07-2012 | #8


Старожил


Сообщения: 415
Благодарности: 257

Профиль | Отправить 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
Благодарности: 0

Профиль | Отправить PM | Цитировать


) работает! КРАСОТА! Спасибо!

для вывода в файл добавляю строку
Echo !Phone_%%A!!EMail_%%A!|grep -vi "(ECHO)">>out.txt
?

Отправлено: 12:28, 17-07-2012 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - Парсинг XML/TXT

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
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




 
Переход