Показать полную графическую версию : [решено] Как создать батники по шаблону в поддиректориях
NuclearBox
26-03-2018, 11:00
Здравствуйте, уважаемые.
Есть папка 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 в поддиректории.
это такое задание или такая блажь?
для последовательного запуска файлов .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
@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
alpap,
Спасибо, конечно, но к цели не приблизился.
Нужно именно то, что описал выше - батник, который создает другие батники внутри поддиректорий по шаблону, с подстановкой файлов по маске (расширению).
На блажь хронически не хватает времени.
megaloman
26-03-2018, 13:06
NuclearBox, Давайте не будем делать батник с кучей строк с перечислением файлов с определённым расширением.
@Echo Off
chcp 1251 >nul
Set "Comm="Z:\Soft\Z.exe" -df -h"
Set "Mask=*.zzz"
FOR %%f IN ("%Mask%") DO %Comm% "%%f"
@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
megaloman, Сердечно!!!
Это именно то, что надо! Я про первый вариант.
из условий остается только, чтобы имена батников соответствовали именам папок, куда они попадают.
Второй вариант (с txt-шаблоном) - однозначно, очень красив. Но к сожалению, Условия требуют ограничиться только одним батником. Хотя, конечно, очень логично использовать легко редактируемый и заменяемый файл-шаблон. Забираю для других ситуаций.
megaloman
26-03-2018, 13:46
@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
megaloman,
Нечеловеческое СПАСИБО!
Нет слов.
Вопрос закрыт полностью!
NuclearBox
27-03-2018, 15:23
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
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
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
Вы хотите, чтобы в папке Root\Folder делался батник в котором будет "Folder\*.zzz" ? Так делать нельзя!
В батнике Folder.bat запущенном из папки Root\Folder не будут найдены файлы, путь к которым прописан как "Folder\*.zzz"
@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
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
@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
megaloman,
Большое спасибо!!! Теперь формирует батники правильно. На тестовой машине.
Но предполагается запуск на большом количестве разношерстных компьютеров, из разных папок, и с выносных дисков.
Попробовал запустить на другом компьютере и с выносного диска - пришлось переписывать путь Set "BoxIn=Z:\Box_In\Root".
Решил заменить на Set "BoxIn=%~dp0" - но тогда работает не корректно.
Не сочтите наглостью еще одну просьбу. Можете ли сделать последний штрих в коде - сделать автоопределение папки запуска ("BoxIn")?
Set "Comm="..." менять не придется, он везде будет один и тот же.
megaloman
28-03-2018, 10:06
Set "BoxIn=%~dp0"
If "%BoxIn:~-1%"=="\" Set "BoxIn=%BoxIn:~0,-1%"
NuclearBox
28-03-2018, 10:27
megaloman,
Работает при любом запуске! Ура!
Огромное Вам спасибо!!!
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.