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

NuclearBox 26-03-2018 11:00 2805503

Как создать батники по шаблону в поддиректориях
 
Здравствуйте, уважаемые.
Есть папка Root с поддиректориями, внутри которых тоже есть поддиректории - на неопределенную глубину.
В них находятся файлы, некоторые из которых имеют расширение .zzz
И есть шаблон батника для последовательного запуска файлов .zzz с приложением Z.exe. Для примера:
-------
@echo off
chcp 1251>nul
Z.exe -df -h 1.zzz
Z.exe -df -h 2.zzz
Z.exe -df -h 3.zzz
...
-------
Нужен батник, который из папки Root сканирует все поддиректории, и где находит файлы .zzz, там создает новый батник по указанному шаблону.
Имя батника должно соответствовать имени поддиректории, где он создан.
1.zzz 2.zzz 3.zzz и т.д. должны быть заменены реальными именами файлов .zzz из поддиректории.
Количество строк вида "Z.exe -df -h *.zzz" должно соответствовать количеству файлов .zzz в поддиректории.

alpap 26-03-2018 11:48 2805519

это такое задание или такая блажь?
Цитата:

для последовательного запуска файлов .zzz с приложением Z.exe
вот одна строка из консоли
Код:

for /f "delims=" %a in ('dir /a-d/b/s "*.zzz"') do Z.exe -df -h "%a"

megaloman 26-03-2018 12:29 2805525

Если молча выполнить предложенную постановку задачи (ИМХО, непродуманная блажь) и в каждой папке создать батник по предложенному шаблону
Код:

@Echo Off

chcp 1251 >nul

Set "BoxIn=Z:\Box_In"
Set "Mask=*.zzz"
Set "Comm="Z:\Soft\Z.exe" -df -h"

Set "BatName=%~nx0.bat"

FOR /R "%BoxIn%" %%d IN (.) DO (
        If Exist "%%~dpnxd\%Mask%" (       
                Echo %%~dpnxd
                >"%%~dpnxd\%BatName%" (
                Echo @Echo off
                Echo chcp 1251 ^>nul
                FOR %%f IN ("%%~dpnxd\%Mask%") DO Echo %Comm% "%%~nxf"
                )
        )
)


NuclearBox 26-03-2018 12:29 2805526

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

megaloman 26-03-2018 13:06 2805540

NuclearBox, Давайте не будем делать батник с кучей строк с перечислением файлов с определённым расширением.
сделаем текстовый файл с шаблоном такого вида, например: Z:\templet.txt
Код:

@Echo Off
chcp 1251 >nul

Set "Comm="Z:\Soft\Z.exe" -df -h"
Set "Mask=*.zzz"

FOR %%f IN ("%Mask%") DO %Comm% "%%f"

И, при наличии в папке файлов с нужным расширением *.zzz скопируем его в эту папку в виде батника
Код:

@Echo Off

chcp 1251 >nul

Set "BoxIn=Z:\Box_In"
Set "Mask=*.zzz"

Set "Templet=Z:\templet.txt"
Set "BatName=%~nx0.bat"

FOR /R "%BoxIn%" %%d IN (.) DO If Exist "%%~dpnxd\%Mask%" Copy "%Templet%" "%%~dpnxd\%BatName%" >nul

При этом при запуске батника в каждой папке последовательно программой
"Z:\Soft\Z.exe" -df -h
будут обработаны все файлы в этой папке по маске *.zzz

NuclearBox 26-03-2018 13:22 2805549

megaloman, Сердечно!!!

Это именно то, что надо! Я про первый вариант.
из условий остается только, чтобы имена батников соответствовали именам папок, куда они попадают.

Второй вариант (с txt-шаблоном) - однозначно, очень красив. Но к сожалению, Условия требуют ограничиться только одним батником. Хотя, конечно, очень логично использовать легко редактируемый и заменяемый файл-шаблон. Забираю для других ситуаций.

megaloman 26-03-2018 13:46 2805553

чтобы имена батников соответствовали именам папок, куда они попадают
Код:

@Echo Off
chcp 1251 >nul

Set "BoxIn=Z:\Box_In"
Set "Mask=*.zzz"
Set "Comm="Z:\Soft\Z.exe" -df -h"

Call :MakeBat "%BoxIn%"
FOR /F "usebackq delims=" %%d IN (`2^>nul Dir "%BoxIn%" /A:D /S /B`) DO Call :MakeBat "%%d"
GoTo :Eof

:MakeBat
        If Exist "%~1\%Mask%" (
                >"%~1\%~nx1.bat" (
                Echo @Echo off
                Echo chcp 1251 ^>nul
                FOR %%f IN ("%~1\%Mask%") DO Echo %Comm% "%%~nxf"
                )
        )
GoTo :Eof

чтобы имена батников соответствовали именам папок, куда они попадают и чтобы не делать кучу строк с наименованием файлов
Код:

@Echo Off
chcp 1251 >nul

Set "BoxIn=Z:\Box_In"
Set "Mask=*.zzz"

Set /A Nbeg=0
For /F "usebackq delims=:" %%i In (`"FINDSTR /B /L /I /N /C:":MakeBatOut" "%~dpnx0""`) DO Set /A Nbeg=%%i

Call :MakeBat "%BoxIn%"
FOR /F "usebackq delims=" %%d IN (`2^>nul Dir "%BoxIn%" /A:D /S /B`) DO Call :MakeBat "%%d"
GoTo :Eof

:MakeBat
        If Exist "%~1\%Mask%" >"%~1\%~nx1.bat" more +%Nbeg% "%~dpnx0"
GoTo :Eof

:MakeBatOut
@Echo Off
chcp 1251 >nul

Set "Comm="Z:\Soft\Z.exe" -df -h"
Set "Mask=*.zzz"

FOR %%f IN ("%Mask%") DO %Comm% "%%f"


NuclearBox 26-03-2018 15:32 2805584

megaloman,
Нечеловеческое СПАСИБО!
Нет слов.
Вопрос закрыт полностью!

NuclearBox 27-03-2018 15:23 2805789

megaloman,
Помогите, пожалуйста, еще немного изменить Ваш код таким образом, чтобы путь к файлам *.zzz был относительным.
То есть, если батник запускается из папки "Z:\Folder1\" , то строка вида
"Z:\Soft\Z.exe" -df -h "Z:\Folder1\Folder2\1.zzz"
принимала бы вид
"Z:\Soft\Z.exe" -df -h "Folder2\1.zzz"

megaloman 27-03-2018 15:48 2805795

NuclearBox, Не догоняю! Какой батник запускается из "Z:\Folder1\" - тот, который генерирует батник, или сгенерированный? Мой скрипт генерирует батники внутри каждой папки и путей для обрабатываемых файлов там нет вообще.
То есть, в папке Z:\Folder1 делается батник Z:\Folder1\Folder1.bat c "Z:\Soft\Z.exe" -df -h "1.zzz"
В папке Z:\Folder1\Folder2 делается батник Z:\Folder1\Folder2\Folder2.bat c "Z:\Soft\Z.exe" -df -h "1.zzz"
Я не понимаю, что такое Folder2\ который надо указать в генерируемом батнике

NuclearBox 27-03-2018 16:07 2805798

megaloman, да-да, Вы правы. Прошу простить за неточность - я просто пытался сам изменить Ваш код, и добавил полный путь к файлам *.zzz.
В Вашем коде, все строки запуска в сгенерированных батниках выглядят так:
"Z:\Soft\Z.exe" -df -h "*.zzz"
Генерирующий батник запускается из папки Root, и генерирует батники во всех подкаталогах, где естьо файлы *.zzz
Нужно добавить к имени файла *.zzz относительный путь.
То есть, если генерирующий батник запускается из Root, и находит в папке Root\Folder\ файлы *.zzz, то чтобы соответствующая строка в батнике, сгенерированном для папки Folder, выглядела так:
"Z:\Soft\Z.exe" -df -h "Folder\*.zzz"

megaloman 27-03-2018 16:16 2805799

Вы хотите, чтобы в папке Root\Folder делался батник в котором будет "Folder\*.zzz" ? Так делать нельзя!
В батнике Folder.bat запущенном из папки Root\Folder не будут найдены файлы, путь к которым прописан как "Folder\*.zzz"
Другое дело, если батник Folder.bat будет расположен в Root\Folder.bat
Код:

@Echo Off
chcp 1251 >nul

Set "BoxIn=Z:\Box_In"
Set "Mask=*.zzz"
Set "Comm="Z:\Soft\Z.exe" -df -h"

Call :MakeBat "%BoxIn%"
FOR /F "usebackq delims=" %%d IN (`2^>nul Dir "%BoxIn%" /A:D /S /B`) DO Call :MakeBat "%%d"
pause
GoTo :Eof

:MakeBat
        If Exist "%~1\%Mask%" (
                Echo %1
                >"%~dp1\%~nx1.bat" (
                Echo @Echo off
                Echo chcp 1251 ^>nul
                FOR %%f IN ("%~1\%Mask%") DO Echo %Comm% "%~nx1\%%~nxf"
                )
        )
GoTo :Eof


NuclearBox 27-03-2018 21:25 2805856

megaloman,
Цитата megaloman:
В батнике Folder.bat запущенном из папки Root\Folder не будут найдены файлы, путь к которым прописан как "Folder\*.zzz" »
Это и не нужно, поскольку "Folder\*.zzz" является частью параметра запуска программы Z.exe, полный путь к которой прописан. Это не путь для сгенерированного батника.

Генерирующий батник запускается из папки Root.
Пусть полный путь к папке Z:\Test\Root , а сам батник назовем Root.bat
Папка Root имеет поддиректории на неопределенную глубину.

Root.bat генерирует батники в каждой поддиректории, где есть файлы *.zzz, на всю глубину, присваивая им имена папок, в которых они генерируются.
Напимер,
Z:\Test\Root\Folder1\Folder1.bat
Z:\Test\Root\Folder1\Folder11\Folder11.bat
Z:\Test\Root\Folder1\Folder12\Folder12.bat
Z:\Test\Root\Folder2\Folder2.bat
Z:\Test\Root\Folder2\Folder21\Folder21.bat
Z:\Test\Root\Folder2\Folder22\Folder22.bat
...
Код
Код:

@Echo Off
chcp 1251 >nul

Set "BoxIn=Z:\Test\Root"
Set "Mask=*.zzz"
Set "Comm="Z:\Soft\Z.exe" -df -h"

Call :MakeBat "%BoxIn%"
FOR /F "usebackq delims=" %%d IN (`2^>nul Dir "%BoxIn%" /A:D /S /B`) DO Call :MakeBat "%%d"
GoTo :Eof

:MakeBat
    If Exist "%~1\%Mask%" (
        >"%~1\%~nx1.bat" (
        Echo @Echo off
        Echo chcp 1251 ^>nul
        FOR %%f IN ("%~1\%Mask%") DO Echo %Comm% "%%~nxf"
        )
    )
GoTo :Eof

(Изменил в нем "BoxIn")
формирует такой батник Z:\Test\Root\Folder1\Folder11\Folder11.bat
-------
@Echo off
chcp 1251>nul
"Z:\Soft\Z.exe" -df -h "1.zzz"
"Z:\Soft\Z.exe" -df -h "2.zzz"
"Z:\Soft\Z.exe" -df -h "3.zzz"
...
-------

А хочу изменить на такой:
-------
@Echo off
chcp 1251>nul
"Z:\Soft\Z.exe" -df -h "Folder1\Folder11\1.zzz"
"Z:\Soft\Z.exe" -df -h "Folder1\Folder11\2.zzz"
"Z:\Soft\Z.exe" -df -h "Folder1\Folder11\3.zzz"
...
-------

Для этого, изменил строку кода
-------
Код:

        FOR %%f IN ("%~1\%Mask%") DO Echo %Comm% "%%~nxf"
-------
на такую
-------
Код:

        FOR %%f IN ("%~1\%Mask%") DO Echo %Comm% "%~1\%%~nxf"
-------
и батник Root.bat стал пописывать полный путь к файлам *.zzz:
-------
@Echo off
chcp 1251>nul
"Z:\Soft\Z.exe" -df -h "Z:\Test\Root\Folder1\Folder11\1.zzz"
"Z:\Soft\Z.exe" -df -h "Z:\Test\Root\Folder1\Folder11\2.zzz"
"Z:\Soft\Z.exe" -df -h "Z:\Test\Root\Folder1\Folder11\3.zzz"
...
-------

Остается как-то построчно избавиться во всех батниках от одинаковой части пути "Z:\Test\Root\",
или прописать в приведенной выше строке вместо полного пути %~1 - относительные пути к файлам *.zzz

megaloman 27-03-2018 22:14 2805866

??? Пытаюсь угадать
Код:

@Echo Off
chcp 1251 >nul

Set "BoxIn=Z:\Box_In\Root"
Set "Mask=*.zzz"
Set "Comm="Z:\Soft\Z.exe" -df -h"

Call :MakeBat "%BoxIn%"
FOR /F "usebackq delims=" %%d IN (`2^>nul Dir "%BoxIn%" /A:D /S /B`) DO Call :MakeBat "%%d"
pause
GoTo :Eof

:MakeBat
        If Exist "%~1\%Mask%" (
                Echo %1
                >"%~1\%~nx1.bat" (
                Echo @Echo off
                Echo chcp 1251 ^>nul
                FOR %%f IN ("%~1\%Mask%") DO Call :Command "%~dpnx1\%%~nxf"
                )
        )
GoTo :Eof

:Command
        Set "Root=%BoxIn%\"
        Set "Param=%~1"
        Call Set "Param=%%Param:%Root%=%%"
        Echo %Comm% "%Param%"
GoTo :Eof


NuclearBox 28-03-2018 00:00 2805881

megaloman,
Большое спасибо!!! Теперь формирует батники правильно. На тестовой машине.
Но предполагается запуск на большом количестве разношерстных компьютеров, из разных папок, и с выносных дисков.
Попробовал запустить на другом компьютере и с выносного диска - пришлось переписывать путь Set "BoxIn=Z:\Box_In\Root".
Решил заменить на Set "BoxIn=%~dp0" - но тогда работает не корректно.
Не сочтите наглостью еще одну просьбу. Можете ли сделать последний штрих в коде - сделать автоопределение папки запуска ("BoxIn")?
Set "Comm="..." менять не придется, он везде будет один и тот же.

megaloman 28-03-2018 10:06 2805914

Код:

Set "BoxIn=%~dp0"
If "%BoxIn:~-1%"=="\" Set "BoxIn=%BoxIn:~0,-1%"


NuclearBox 28-03-2018 10:27 2805917

megaloman,
Работает при любом запуске! Ура!
Огромное Вам спасибо!!!


Время: 23:03.

Время: 23:03.
© OSzone.net 2001-