Существует несколько решений, чтобы проверить, содержит ли каталог подкаталоги.
Во всех решениях ниже папка для временных файлов, на которые ссылается %TEMP%
, используется в качестве примера.
Решение 1 с использованием FOR / D :
@echo off
set "FolderCount=0"
for /D %%I in ("%TEMP%\*") do set /A FolderCount+=1
if %FolderCount% == 0 (
echo Temporary files folder has no non-hidden subfolder.
) else if %FolderCount% == 1 (
echo Temporary files folder has one non-hidden subfolder.
) else (
echo Temporary files folder has %FolderCount% non-hidden subfolders.
)
pause
Проблема с этим решением заключается в том, что FOR с опцией /D
для поиска каталогов, соответствующих шаблону подстановочного знака *
в указанном каталоге для временных файлов игнорирует каталоги со скрытым набором атрибутов. По этой причине команда SET с выражением арифметики c для увеличения значения переменной среды FolderCount
на единицу в каждом каталоге не выполняется для каталога со скрытым набором атрибутов.
Краткая версия этого решения без подсчета папок:
@echo off
for /D %%I in ("%TEMP%\*") do goto HasFolders
echo Temporary files folder has no non-hidden subfolder.
goto EndBatch
:HasFolders
echo Temporary files folder has non-hidden subfolders.
:EndBatch
pause
Выход l oop с командой GOTO on FOR назначил имя не скрытого каталога с переменной l oop.
Решение 2 с использованием FOR / F и DIR :
@echo off
set "FolderCount=0"
for /F "eol=| delims=" %%I in ('dir "%TEMP%" /AD /B 2^>nul') do set /A FolderCount+=1
if %FolderCount% == 0 (
echo Temporary files folder has no subfolder.
) else if %FolderCount% == 1 (
echo Temporary files folder has one subfolder.
) else (
echo Temporary files folder has %FolderCount% subfolders.
)
pause
FOR с опцией /F
и набором, заключенным в '
, приводит к фоновому запуску еще одного командного процесса с %ComSpec% /c
и командной строки в '
, добавляемой в качестве дополнительных аргументов. Выполнение выполнено с Windows, установленным на C:\Windows
:
C:\Windows\System32\cmd.exe /c dir "C:\Users\UserName\AppData\Local\Temp" /AD /B 2>nul
DIR , выполненным в фоновом режиме поиска команд
- в указанном каталоге для временных файлов
- только для каталогов из-за опции
/AD
(каталог атрибутов) - с включением также каталогов со скрытым набором атрибутов из-за опции
/AD
переопределяет значение по умолчанию /A-H
(все атрибуты, кроме атрибута) скрыто) - и выводит их в открытом формате из-за опции
/B
, которая приводит к игнорированию стандартных каталогов .
(текущий каталог) и ..
(родительский каталог) и печати только имен каталогов без пути .
Вывод DIR записывается для обработки STDOUT (стандартный вывод) запущенного фонового процесса команды. Ничего не выводится, если в указанном каталоге нет подкаталога.
Выводится сообщение об ошибке для обработки STDERR (стандартная ошибка) процесса фоновой команды, если указанный каталог не существуют вообще. Это сообщение об ошибке будет перенаправлено командным процессом, выполняющим командный файл, на собственный дескриптор STDERR и будет выведено в окне консоли. По этой причине 2>nul
добавляется к командной строке DIR для подавления сообщения об ошибке в фоновом командном процессе путем перенаправления его из дескриптора STDERR на устройство NUL .
Прочтите статью Microsoft о Использование операторов перенаправления команд для объяснения 2>nul
. Оператор перенаправления >
должен быть экранирован с помощью символа вставки ^
в FOR командной строке для интерпретации как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR который выполняет встроенную dir
командную строку в отдельном командном процессе, запущенном в фоновом режиме.
FOR с параметром /F
захватывает выходные данные, записанные для обработки STDOUT запущенного фонового командного процесса и обрабатывает вывод построчно после того, как запущенный cmd.exe
завершил себя после завершения выполнения внутренней команды DIR .
Пустые строки по умолчанию игнорируются FOR , которого здесь нет.
FOR по умолчанию разделит строку на подстроки с использованием обычного пробела и символа горизонтальной табуляции в качестве разделителей строк и назначит только первый разделенный пробел / табуляцию строка к указанной переменной l oop I
. Такое поведение разделения строк здесь не требуется и по этой причине отключается с помощью параметра delims=
, который определяет пустой список разделителей строк.
FOR будет игнорировать также строки, в которых первая подстрока после разбиения строки на подстроки начинается с символа конца строки по умолчанию ;
. Режим разделения строк уже отключен, но имя каталога может начинаться необычно с точки с запятой. Такое имя каталога будет игнорироваться FOR . Поэтому опция eol=|
определяет вертикальную черту как символ конца строки, который не может иметь имя каталога, и поэтому каталог FOR не игнорируется. См. Также статью Microsoft о Именовании файлов, путей и пространств имен .
Имя каталога, присвоенное переменной l oop I
, фактически не используется из-за FOR выполняет для каждого имени каталога только команду SET с арифметическим c выражением для увеличения значения переменной среды FolderCount
на единицу.
Переменная среды FolderCount
содержит количество подпапок в указанном каталоге независимо от скрытого атрибута.
Краткая версия этого решения без подсчета папок:
@echo off
for /F "eol=| delims=" %%I in ('dir "%TEMP%" /AD /B 2^>nul') do goto HasFolders
echo Temporary files folder has no subfolder.
goto EndBatch
:HasFolders
echo Temporary files folder has subfolders.
:EndBatch
pause
Выход l oop завершается командой GOTO on FOR присвоил первое имя каталога переменной l oop.
Решение 3 с использованием DIR и FINDSTR :
@echo off
dir "%TEMP%" /AD /B 2>nul | %SystemRoot%\System32\findstr.exe /R "^." >nul
if errorlevel 1 (
echo Temporary files folder has no subfolder.
) else (
echo Temporary files folder has subfolders.
)
pause
Вывод DIR , как описано выше, выполненный cmd.exe
, обрабатывающим пакетный файл, перенаправляется из STDOUT командного процесса в STDIN (stan ввод dard) FINDSTR , который ищет строки, имеющие хотя бы один символ. Найденные строки - это все строки с именем каталога, выводимым DIR . Этот результат поиска не представляет особого интереса и поэтому перенаправляется на устройство NUL для его подавления.
FINDSTR завершается с 1
, если строка не может быть найдена и с 0
при обнаружении хотя бы одной строки. Код выхода FINDSTR назначается командным процессором Windows для ERRORLEVEL
, который оценивается с помощью условия IF .
IF условие истинно, если выходное значение FINDSTR , присвоенное ERRORLEVEL
, равно больше или равно 1
, что не соответствует ни одному каталогу, найденному DIR и т. д. FINDSTR не удалось найти ни одной строки с хотя бы одним символом.
Это решение также можно записать в виде одной командной строки:
dir "%TEMP%" /AD /B 2>nul | %SystemRoot%\System32\findstr.exe /R "^." >nul && echo Temporary files folder has subfolders.|| echo Temporary files folder has no subfolder.
См. одну строку с несколькими командами, использующими Windows командный файл для объяснения операторов &&
и ||
, используемых здесь для оценки кода выхода FINDSTR .
Дополнительные советы:
Было бы хорошо сначала проверить, существует ли каталог вообще, прежде чем проверять, содержит ли он какие-либо подкаталоги. Это можно сделать во всех трех приведенных выше решениях, используя сначала после @echo off
if not exist "%TEMP%\" (
echo Folder "%TEMP%" does not exist.
pause
exit /B
)
. Для понимания используемых команд и их работы откройте окно командной строки , выполните там следующие команды и полностью прочитайте все справочные страницы, отображаемые для каждой команды.
cmd /?
dir /?
echo /?
exit /?
findstr /?
for /?
goto /?
if /?
pause /?
set /?