Компьютерный форум 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=309836)

Лео Lапыч 31-12-2015 13:30 2590130

Задача: парсинг текстового файла
 
Добрый день, системные администраторы и программисты-разработчики!

Давно хочу решить одну задачку средствами командного интерпретатора Windows, но всё времени не хватает углубиться в тонкости языка.
Задача возникла как скрипт ловушки для системы управления версиями Subversion. В частном случае я её решил, но хотелось бы в общем.
Итак, внимание, задачка:

Исходные данные. Есть текстовый файл, структура которого следующая:
Код:

Path1 - Mask1_1
Mask1_...
Mask1_N-1
Mask1_N

Path... - Mask..._1
Mask..._...
Mask..._N-1
Mask..._N

PathM-1 - MaskM-1_1
MaskM-1_...
MaskM-1_N-1
MaskM-1_N

PathM - MaskM_1
MaskM_...
MaskM_N-1
MaskM_N

Пояснения: файл содержит путь, потом символы пробел, минус, пробел и первую маску; последующие маски, относящиеся к этому пути, начинаются с новой строки (CRLF); признаком окончания списка масок, относящихся к пути, являются пустая строка (CRLFCRLF) или конец файла. Дальше всё может повторится для другого пути. Количество путей и масок не ограничено (в разумных пределах).

Требуется получить в локальную переменную командного пакета строку вида:
Код:

%Result% = "Path1\Mask1_1 Path1\Mask1_... Path1\Mask1_N-1 Path1\Mask1_N ... Path...\Mask..._1 Path...\Mask..._... Path...\Mask..._N-1 Path...\Mask..._N PathM-1\MaskM-1_1 PathM-1\MaskM-1_... PathM-1\MaskM-1_N-1 PathM-1\MaskM-1_N PathM\MaskM_1 PathM\MaskM_... PathM\MaskM_N-1 PathM\MaskM_N"
То есть разложить этот файл в строку, содержащую пути с маской, разделённые пробелом. Кроме того, все символы разделителя пути / должны быть преобразованы в \.
Возможен, конечно, косяк, если в имени пути или маске содержатся пробелы, либо в имени пути содержатся подряд идущие символы пробел, минус, пробел. Но такие случаи пока от условий задачи отсечём.

Пример:
На основе файла
Код:

Projects/Builder - *.~*
*.$*
*.obj

Projects/CSharp - *.cache*
*.suo

Должна получится строка
Код:

Projects\Builder\*.~* Projects\Builder\*.$* Projects\Builder\*.obj Projects\CSharp\*.cache* Projects\CSharp\*.suo
Более высокоуровневые языки для решения использовать пока не хочу. Так что у кого на досуге будет время поломать голову, прошу поделиться мыслями.
Благодарен уже за уделённое внимание!

Foreigner 31-12-2015 14:24 2590140

Цитата:

Цитата Лео Lапыч
На основе файла »

Код:

@echo off
setlocal

for /f "tokens=*" %%i in (1.txt) do call:0 %%i
echo.
goto:eof

:0
if not "%2"=="" (0>nul set /p="%~1\%3 " & set p=%~1) else (0>nul set /p="%p%\%1 ")


Лео Lапыч 03-01-2016 21:38 2590876

Спасибо, Иностранец. Честно говоря, это читерство какое-то. Ничего не понял. Разбираться не стал, ибо столько водки дома уже нету. Скрипт почти работает.
Выводит
Код:

Projects/Builder\*.~* Projects/Builder\*.$* Projects/Builder\*.obj Projects/CSharp\*.cache* Projects/CSharp\*.suo
А надо
Код:

Projects\Builder\*.~* Projects\Builder\*.$* Projects\Builder\*.obj Projects\CSharp\*.cache* Projects\CSharp\*.suo
По условию задачи
Цитата:

Кроме того, все символы разделителя пути / должны быть преобразованы в \.
А ещё хотелось бы в конце
Код:

echo %Result%
в которой бы и был результат преобразований.

Мне необходимо вызывать эту :0 в нескольких местах моего скрипта. Предусмотрено ли что-то вроде ret, чтобы вернуться в место после вызова? Или goto - наше всё?

И ещё. Всё таки для борьбы с пробелами в путях и масках, пусть каждая полная маска будет заключена в кавычки.
То есть
Код:

"Projects\Builder\*.~*" "Projects\Builder\*.$*" "Projects\Builder\*.obj" "Projects\CSharp\*.cache*" "Projects\CSharp\*.suo"
Спасибо ещё разок!

Iska 03-01-2016 22:11 2590886

Цитата:

Цитата Лео Lапыч
По условию задачи
Цитата:

Кроме того, все символы разделителя пути / должны быть преобразованы в \.

В принципе, пока окончательно не выпилили POSIX — для ОС NT разницы быть не должно. Другое дело, если какие-то утилиты не пользуются функциями ОС, а сами пытаются делать такие операции как разбивка пути на составляющие по символу «/».

Цитата:

Цитата Лео Lапыч
Предусмотрено ли что-то вроде ret, чтобы вернуться в место после вызова? Или goto - наше всё? »

Скрытый текст
Код:


call :Метка

exit /b 0

:Метка

exit /b 0


Можно даже значения возвращать в переменную окружения :).

Лео Lапыч 04-01-2016 10:32 2590960

Цитата:

Цитата Iska
В принципе, пока окончательно не выпилили POSIX — для ОС NT разницы быть не должно. Другое дело, если какие-то утилиты не пользуются функциями ОС, а сами пытаются делать такие операции как разбивка пути на составляющие по символу «/». »

Проверил. Хавает и так, и так. Так что условие
Цитата:

Цитата Лео Lапыч
Кроме того, все символы разделителя пути / должны быть преобразованы в \. »

убираем.

Про exit /b понял. Спасибо!

Цитата:

Цитата Iska
Можно даже значения возвращать в переменную окружения . »

Это лишнее.

Foreigner 04-01-2016 13:04 2591008

Цитата:

Цитата Лео Lапыч
все символы разделителя пути / должны быть преобразованы в \ »

Код:

@echo off
setlocal

for /f "tokens=*" %%i in (1.txt) do call:0 %%i
goto:eof

:0

set "a=%~1"
if not "%2"=="" (0>nul set /p="%a:/=\%\%3 " & set p=%a:/=\%) else (0>nul set /p="%p%\%a% ")


Лео Lапыч 04-01-2016 13:41 2591027

Спасибо! А что насчёт
Цитата:

Цитата Лео Lапыч
А ещё хотелось бы в конце
Код:

echo %Result%
в которой бы и был результат преобразований. »

и
Цитата:

Цитата Лео Lапыч
Всё таки для борьбы с пробелами в путях и масках, пусть каждая полная маска будет заключена в кавычки. То есть
Код:

"Projects\Builder\*.~*" "Projects\Builder\*.$*" "Projects\Builder\*.obj" "Projects\CSharp\*.cache*" "Projecs\CSharp\*.suo"»

?

Foreigner 04-01-2016 15:21 2591081

Тогда так:
Код:

@echo off
setlocal

for /f "tokens=*" %%i in (1.txt) do call:0 %%i

set "result=%result:/=\%"
echo %result%

goto:eof

:0

if not "%2"=="" (set "p=%~1" && set res="%~1\%3") else (set res="%p%\%1")
if defined result (set result=%result% %res%) else (set result=%res%)


Лео Lапыч 05-01-2016 22:48 2591525

Спасибо всем!
Скрипт автоматизации добавления новых файлов под версионный контроль при фиксации обновлений теперь работает в общем виде и правильно учитывает свойства svn:global-ignores и svn:ignore, чего и требовалось от него добиться.


Время: 21:59.

Время: 21:59.
© OSzone.net 2001-