【问题标题】:How can I get special directory list by batch file?如何通过批处理文件获取特殊目录列表?
【发布时间】:2017-08-17 06:53:21
【问题描述】:

以下是我使用的目录。

C:\test>dir /s /b /a:d
C:\test\A
C:\test\A\a
C:\test\A\b
C:\test\A\a\a
C:\test\A\a\b
C:\test\A\a\a\20160101
C:\test\A\a\a\20160816
C:\test\A\a\b\20160101
C:\test\A\a\b\20160816
C:\test\A\b\a
C:\test\A\b\b
C:\test\A\b\a\20160101
C:\test\A\b\a\20160816
C:\test\A\b\b\20160101
C:\test\A\b\b\20160816

使用dir /s /b /a:d 获取所有文件夹目录。

如何通过批处理文件将文件列表放到 3 层测试文件夹下?

我想得到以下列表:

C:\test\A
C:\test\A\a
C:\test\A\b
C:\test\A\a\a
C:\test\A\a\b
C:\test\A\b\a
C:\test\A\b\b

【问题讨论】:

  • 你到底想做什么?进入嵌套目录的批处理文件?
  • @PradeepDeshmukh 我编辑我的问题,感谢提问。
  • 所以你只希望列表显示在 cmd 选项卡上吗?
  • 是的,比如使用 dir 命令。
  • 没有。单个dir 命令不起作用,您需要某种for 循环。

标签: batch-file directory


【解决方案1】:
@echo off
cls
for /f "delims=" %%I in ('dir /s /b /ad') do (
    call :countAppr "%%~I"
)
exit /b

:countAppr
set "string=%~1"
set count=0
:again
set "oldstring=%string%"
set "string=%string:*\=%"
set /a count+=1
if not "%string%" == "%oldstring%" goto :again
if %count% leq 4 echo( %~1
exit /b

解释:

  • 循环完整的文件
  • 计数\ 出现在文件夹名称中
  • 如果小于等于4,返回文件夹名称

要在文件夹级别显示文件夹,请将leq 更改为equ。深度也可以改变。

注意:部分脚本是从 Stephan 的回答 here 复制和编辑的。

【讨论】:

  • 这个命令只能显示3级吗?例如,只显示C:\test\A\a\aC:\test\A\a\bC:\test\A\b\aC:\test\A\b\b
  • 是的,将leq 更改为equ
  • 谢谢,看起来很棒!
  • @Adinia 感谢您的建议。我已经移除了那些 cmets,但我不确定是否还有剩余。
【解决方案2】:

一个简单的解决方案是使用robocopy 命令。虽然用于文件复制操作,但它包含一个/L 开关,用于请求不复制但要列出。调整开关以删除您可以使用的不需要的信息

robocopy . . /e /nfl /njh /njs /ns /lev:4 /l

这将递归(/e)列出(/l)当前文件夹下的所有选定元素,不显示文件信息(/nfl),没有作业标题(/njh),没有摘要(/njs ),没有文件/大小计数器 (/ns) 用于深度搜索四个级别(当前文件夹加上下面三个所需级别)

robocopy 命令的输出在行首包含一些制表符/空格。如果你需要删除它们,你可以使用类似的东西

for /f "tokens=*" %a in ('robocopy . . /e /nfl /njh /njs /ns /lev:4 /l') do echo %a

或者,从批处理文件中

for /f "tokens=*" %%a in ('robocopy . . /e /nfl /njh /njs /ns /lev:4 /l') do echo %%a

已编辑如果robocopy 的使用有问题(在您的系统中不可用/不允许),或者您需要(来自 cmets)将输出限制为仅最后一个级别,您可以使用一些东西喜欢

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Retrieve folder from command line, default current folder
    for /f "delims=" %%a in ("%~f1\.") do set "target=%%~fa"

    echo ----------------------------------------------------------------------
    rem Call subroutine searching for ALL folders up to 3 levels
    call :treeDump target 3


    echo ----------------------------------------------------------------------
    rem Call subroutine searching for folders ONLY 3 levels deep
    call :treeDump target 3 true

    goto :eof

rem Recursive folder search    
:treeDump targetVar maxLevel forceLevel
    rem targetVar  = name of variable containing the folder to iterate
    rem maxLevel   = how many levels to search under target 
    rem forceLevel = only show the last requested level

    setlocal disabledelayedexpansion
    rem Check we are not searching too deep
    2>nul set /a "nextLevel=%~2-1", "1/(%~2+1)" || goto :eof

    rem Retrieve folder to iterate
    setlocal enabledelayedexpansion & for %%a in ("!%~1!") do endlocal & (
        rem Determine if current level must be shown
        if "%~3"=="" (
            echo %%~fa
        ) else (
            if %nextLevel% lss 0 echo %%~fa
        )
        rem If not at the last level, keep searching
        if %nextLevel% geq 0 for /d %%b in ("%%~fa\*") do (
            set "target=%%~fb" 
            call :treeDump target %nextLevel% "%~3"
        )
    )
    goto :eof

它使用递归函数来遍历目录树。对于找到的每个文件夹,如果我们不在所需的级别,则会枚举子文件夹并为每个文件夹再次调用该函数。

【讨论】:

  • 兼容性警报? OP没有说明他/她的操作系统,但是XP用户需要为robocopy安装资源包。
  • 这个命令只能显示3级吗?例如,只显示C:\test\A\a\aC:\test\A\a\bC:\test\A\b\aC:\test\A\b\b
  • @Peggy 是的,MC ND 的解决方案可以工作,但它需要我使用的相同代码。
  • 感谢您的解决方案,robocopy 在我的系统中可用。
  • 我尝试编辑你的代码,我怎么只能显示C:\test\A\a\aC:\test\A\a\bC:\test\A\b\aC:\test\A\b\b
猜你喜欢
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
  • 2020-04-19
  • 2020-08-22
  • 1970-01-01
  • 1970-01-01
  • 2012-07-07
相关资源
最近更新 更多