Windows Batch File Looping по каталогам для обработки файлов?
Хорошо, я программист PHP и, к сожалению, по причинам, которые я не буду объявлять для краткости, мне нужно написать / использовать пакетный файл, который обрабатывает некоторые изображения для меня.
У меня есть одна папка, заполненная вложенными папками, внутри каждой из этих вложенных папок есть еще одна папка, которая содержит несколько изображений TIF, количество изображений в каждой папке различается. У меня также есть командный файл, давайте назовем его ProcessImages.bat для Windows, на который вы можете "сбросить" эти TIF-файлы (или, очевидно, указать их в списке командной строки при вызове bat); на котором он создает новую папку со всеми моими процессами изображений на основе имеющегося у меня EXE.
Хорошо, что, поскольку файл bat использует путь из папок, которые вы "перетаскиваете" на него, я могу выбрать все TIF-файлы одной папки и отбросить их для обработки... но так как я продолжаю делать это вручную для 300 или около того папок TIF, которые у меня есть, я считаю, что моя система так невероятно рушится, и если бы я мог обрабатывать только одну из них за один раз (не делая это вручную), это было бы замечательно.
Все это говорит... может кто-то указать мне правильное направление (для файла bat Windows AMATEUR) таким образом, чтобы я мог написать сценарий Windows bat, который я могу вызвать изнутри каталога и проследить его через ВСЕ каталоги, содержащиеся внутри этот каталог... и запустить мой пакетный файл обработки для каждого набора изображений по одному?
Заранее спасибо!
Тайлер
6 ответов
Вы можете написать рекурсивный алгоритм в Batch, который дает вам точный контроль над тем, что вы делаете в каждом вложенном подкаталоге:
@echo off
call :treeProcess
goto :eof
:treeProcess
rem Do whatever you want here over the files of this subdir, for example:
for %%f in (*.tif) do echo %%f
for /D %%d in (*) do (
cd %%d
call :treeProcess
cd ..
)
exit /b
Решение Aacini работает, но вы можете сделать это в одной строке:
for /R %%f in (*.tif) do echo "%%f"
Решение Джека работает лучше всего для меня, но мне нужно сделать это для сетевого UNC-пути (общий ресурс cifs/smb), поэтому необходимо внести небольшие изменения:
for /R "\\mysrv\imgshr\somedir" %%f in (*.tif) do echo "%%f"
Оригинальный совет для этого метода здесь
Публикация здесь, как кажется, самый популярный вопрос по этому делу.
Вот старая жемчужина, которую мне наконец удалось найти в интернете: sweep.exe.
Он выполняет предоставленную команду в текущем каталоге и во всех его подкаталогах.
Предположим, у вас есть какая-то программа, которая обрабатывает все файлы в каталоге (но варианты использования действительно намного шире):
:: For example, a file C:\Commands\processimages.cmd which contains:
FOR %%f IN (*.png) DO whatever
Итак, вы хотите запустить эту программу в текущем каталоге и во всех подкаталогах:
:: Put sweep.exe in your PATH, you'll love it!
C:\ImagesDir> sweep C:\Commands\processimages.cmd
:: And if processimages.cmd is in your PATH too, the command becomes:
C:\ImagesDir> sweep processimages
Плюсы: вам не нужно изменять исходную программу, чтобы она обрабатывала подкаталоги. У вас есть выбор для обработки подкаталогов, только если вы этого хотите. И эта команда настолько проста и приятна в использовании.
Con: Может произойти сбой с некоторыми командами (содержащие пробелы, кавычки, я не знаю). Смотрите эту ветку для примера.
Я знаю, что это не рекурсия (итерация по перечисляемым подкаталогам?), Но она может работать лучше для некоторых приложений:
for /F "delims=" %%i in ('dir /ad /on /b /s') do (
pushd %%i
dir | find /i "Directory of"
popd
)
Замените 3-ю строку любой командой, которая может вам понадобиться.
dir / ad - список только каталогов
Крутая вещь - pushd не нуждается в кавычках, если пробелы в пути.
rem Replace "baseline" with your directory name
for /R "baseline" %%a in (*) do (
echo %%a
)