检查目录中是否存在任何文件夹。

3

CMD.如何检查一个目录是否包含文件夹(名称未指定)?其他文件将被忽略。

如果是任何 .txt 文件的情况,它看起来有点像这样:

if exist * .txt

我如何使用“任何”文件夹执行此操作?

3个回答

1
有多种方法可以检查一个目录是否包含子目录。
在下面的所有解决方案中,临时文件夹的路径引用了“%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

这个解决方案的问题在于使用选项/DFOR命令来搜索指定目录中匹配通配符模式*的目录,会忽略设置了隐藏属性的目录。因此,对于设置了隐藏属性的目录,无法执行用算术表达式递增环境变量FolderCount值的SET命令。
不计算文件夹数量的简化版本解决方案如下:
@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

循环使用GOTO命令退出,FOR将非隐藏目录的第一个名称分配给循环变量。
使用FOR /FDIR的解决方案2:
@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

使用选项/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句柄,并在控制台窗口中输出。因此,在DIR命令行末尾添加了"2>nul",通过将错误消息从STDERR句柄重定向到NUL设备来抑制后台命令进程中的错误消息。
阅读微软文章使用命令重定向运算符,了解"2>nul"的解释。在FOR命令行上,重定向运算符">"必须用插入符号"^"进行转义,以便在Windows命令解释器在执行嵌入的dir命令行之前处理该命令行时将其解释为字面字符。FOR命令会在后台启动一个单独的命令进程来执行嵌入的dir命令行。

FOR 带有选项 /F 可以捕获启动的后台命令进程的标准输出(STDOUT)并在启动的 cmd.exe 执行完内部命令 DIR 后逐行处理输出。

默认情况下,FOR 会忽略空行,但这里没有空行。

FOR 默认会将每行拆分为子字符串,使用普通空格和水平制表符作为字符串分隔符,并将第一个空格/制表符分隔的字符串赋值给指定的循环变量 I。但在这种情况下,不需要进行行拆分,因此通过使用选项 delims= 来禁用该行为,即定义一个空的字符串分隔符列表。

FOR 会忽略以默认换行符 ; 开始的行中的文本。已禁用行分割行为,但目录名可以以分号开头。这样的目录名将被 FOR 忽略。因此,选项 eol=| 将竖线定义为换行符,而没有目录名可以使用该字符,因此 FOR 不会忽略任何目录。另请参阅 Microsoft 文档页面 Naming Files, Paths, and Namespaces

循环变量 I 分配的目录名实际上并未使用,因为 FOR 对每个目录名执行的只是一个命令 SET,用于通过算术表达式将环境变量 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

循环使用GOTO命令退出,FOR将目录的第一个名称分配给循环变量。
使用DIR和FINDSTR的解决方案3:
@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

如上所述,由 cmd.exe 执行的 DIR 命令的输出被重定向,从命令进程的 STDOUT(标准输出)传递给 FINDSTR,后者搜索至少具有一个字符的行。找到的行都是由 DIR 输出的目录名行。这个搜索结果并不真正感兴趣,因此被重定向到设备 NUL 来抑制它。

FINDSTR 若未找到任何字符串则以 1 退出,若至少找到一个字符串则以 0 退出。Windows 命令处理器将 FINDSTR 的退出代码赋值给 ERRORLEVEL,并进行评估与 IF 条件判断。

如果将 FINDSTR 分配给 ERRORLEVEL 的退出值为 1 或更大,则条件 IF 为真,表示 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之后使用first来实现。
if not exist "%TEMP%\" (
    echo Folder "%TEMP%" does not exist.
    pause
    exit /B
)

要理解所使用的命令及其工作原理,请打开一个命令提示符窗口,在那里执行以下命令,并完整和仔细阅读每个命令显示的帮助页面。
  • cmd /?
  • dir /?
  • echo /?
  • exit /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • set /?

0

如果您只想使用cmd.exe shell控制台查看是否有任何目录:

DIR /A:D

如果您想在 .bat 文件脚本中检查它:
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

DIR "你的目录" /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         

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接