在dos中为dir命令设置Recursive-Depth

时间:2012-09-18 14:38:25

标签: windows recursion cmd directory directory-structure

我目前正在使用以下命令列出一些目录:

dir /b /s /AD > c:\temp\dir_list.txt

这给了我几乎所需的清单。但这是太多的数据,因为有些文件夹有很多子文件夹,我不希望在我的列表中看到。

是否可以将命令的递归深度限制为-lets say-3?

c:\dir_1\dir_2\dir_3\dir_foo

所以如果我在c:>中执行上面例子中的命令我不想看到dir_foo目录,只看dir_n的目录......

也许没有批处理/ vb脚本?

3 个答案:

答案 0 :(得分:19)

我确信可以编写一个列出n级目录的复杂命令。但是很难记住语法和容易出错的情况。每次想要更改级别数时都需要更改。

使用简单的脚本要好得多。

5年后编辑 - 实际上,自Vista之后就有了一个简单的衬垫。 See my new ROBOCOPY solution.

这是一个执行深度优先列表的批处理解决方案。 DIR / S命令执行广度优先列表,但我更喜欢这种深度优先格式。

@echo off
setlocal
set currentLevel=0
set maxLevel=%2
if not defined maxLevel set maxLevel=1

:procFolder
pushd %1 2>nul || exit /b
if %currentLevel% lss %maxLevel% (
  for /d %%F in (*) do (
    echo %%~fF
    set /a currentLevel+=1
    call :procFolder "%%F"
    set /a currentLevel-=1
  )
)
popd

广度第一版几乎相同,只需要额外的FOR循环。

@echo off
setlocal
set currentLevel=0
set maxLevel=%2
if not defined maxLevel set maxLevel=1

:procFolder
pushd %1 2>nul || exit /b
if %currentLevel% lss %maxLevel% (
  for /d %%F in (*) do echo %%~fF
  for /d %%F in (*) do (
    set /a currentLevel+=1
    call :procFolder "%%F"
    set /a currentLevel-=1
  )
)
popd

两个脚本都需要两个参数:

arg1 =要列出的根目录的路径

arg2 =要列出的等级数。

因此,要列出当前目录的3个级别,可以使用

listDirs.bat . 3

要列出不同目录的5个级别,可以使用

listDirs.bat "d:\my folder\" 5

答案 1 :(得分:7)

在这段时间(5年)之后,我刚刚在一个简单的命令行上偶然发现了一直可用的衬垫。 ROBOCOPY自Vista以来一直是标准的Windows实用程序,可通过Windows资源工具包提供给XP。

robocopy . . /l /s /njh /njs /ns /lev:4 >c:\temp\dir_list.txt

说明

    /L :: List only - don't copy, timestamp or delete any files.
    /S :: copy Subdirectories, but not empty ones.
  /NJH :: No Job Header.
  /NJS :: No Job Summary.
   /NS :: No Size - don't log file sizes.
/LEV:n :: only copy the top n LEVels of the source directory tree.

/lev:n选项包括计数中的根,并且您需要3个子目录级别,这就是我为该值添加1的原因。

进一步处理

输出并不完美,因为根文件夹包含在输出中,并且每个路径都包含固定宽度的前导空格。您可以使用FOR /F方便地消除根路径以及前导空格。

(for /f "skip=2 tokens=*" %A in ('robocopy . . /l /s /njh /njs /ns /lev:4') do @echo %A) >c:\temp\dir_list.txt

ROBOCOPY输出包含一个初始空行,这就是skip必须为2而不是1的原因。

每条路径都以\结尾。我喜欢这个功能,因为它很明显我们列出了文件夹而不是文件。如果您确实要删除尾随\,则可以添加额外的FOR

(for /f "skip=2 tokens=*" %A in ('robocopy . . /l /s /njh /njs /ns /lev:4') do @for %B in ("%A.") do @echo %~fB) >c:\temp\dir_list.txt

但命令变得有点笨拙。将此技术合并到一个实用程序批处理文件中应该很容易,该文件将根路径和级别作为参数。如果将命令放在批处理脚本中,则必须记住将百分比加倍。

答案 2 :(得分:3)

这是一个基于@dbenham的深度优先列表解决方案的解决方案 并且还可以设置最低级别

@echo off
setlocal
set currentLevel=0
set maxLevel=%2
if not defined maxLevel set maxLevel=1
set minLevel=%3
if not defined minLevel set minLevel=0

:procFolder
pushd %1 2>nul || exit /b
if %currentLevel% lss %maxLevel% (
  for /d %%F in (*) do (
    if %currentLevel% geq %minLevel% echo %%~FF
    set /a currentLevel+=1
    call :procFolder "%%F"
    set /a currentLevel-=1
  )
)
popd

要设置最低级别,请将其作为第3个参数提供 例如:要从第2级列到第5级,您可以使用

listDirs.bat target_path 5 2

或者,您可以通过将此参数留空

从基本级别列出
listDirs.bat target_path 5