Проверьте, есть ли какие-либо папки в каталоге - PullRequest
1 голос
/ 29 февраля 2020

CMD. Как проверить, содержит ли каталог папку / s (имя не указано)? Другие файлы игнорируются.

Если бы это было в случае любого файла .txt, это выглядело бы примерно так:

, если существуют * .txt

Как мне сделать это с «любой» папкой?

Ответы [ 4 ]

0 голосов
/ 01 марта 2020

Существует несколько решений, чтобы проверить, содержит ли каталог подкаталоги.

Во всех решениях ниже папка для временных файлов, на которые ссылается %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 /?
0 голосов
/ 29 февраля 2020

Вы можете использовать команду find

Пример:

find <starting_search_directory> -type d -name "*folder_2020*" -print

Он найдет все каталоги (-type d), которые содержат "folder_2020" в их имени каталога рекурсивно из starting_search_directory каталог

0 голосов
/ 29 февраля 2020

Если вы просто хотите использовать консоль оболочки cmd.exe, чтобы увидеть, есть ли какие-либо каталоги:

DIR /A:D

Если вы хотите проверить это в скрипте .bat file:

SET "HASDIR=false"
FOR /F "eol=| delims=" %%A IN ('DIR /B /A:D') DO (SET "HASDIR=true")
IF /I "%HASDIR%" == "true" (
    REM Do things about the directories.
)
ECHO HASDIR is %HASDIR%
0 голосов
/ 29 февраля 2020

DIR "your directory" /ad, например DIR C:\Users /ad показывает все папки, которые находятся внутри C: \ Users



 Displays a list of files and subdirectories in a directory.

 DIR [ drive:][path][filename] [/A[[:]attributes]] [/B] [/C] [/D] [/L] [/N]
  [/O[[:]sortorder]] [/P] [/Q] [/R] [/S] [/T[[:]timefield]] [/W] [/X] [/4]

  [drive:][path][filename]
          Specifies drive, directory, and/or files to list.

  /A          Displays files with specified attributes.
  attributes   D  Directories                R  Read-only files
           H  Hidden files               A  Files ready for archiving
           S  System files               I  Not content indexed files
           L  Reparse Points         
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...