windows 在dos中为dir命令设置递归深度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12479250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 09:53:19  来源:igfitidea点击:

Set Recursive-Depth for dir command in dos

windowsrecursioncmddirectorydirectory-structure

提问by Sauer

I'm currently using the following command to list some directories:

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

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

This gives me almost the list that I need. But it is way too much data, because some folders have very many subfolders, that I don't want to see in my listing.

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

Is it possible, to limit the recursion depth of the command to -lets say- 3?

是否有可能将命令的递归深度限制为 -let say- 3?

c:\dir_1\dir_2\dir_3\dir_foo

So if I execute the command in the above example in c:> I don't want to see the dir_foo directory, but just the dir_n ones...

因此,如果我在 c:> 中执行上述示例中的命令,我不想看到 dir_foo 目录,而只想看到 dir_n 目录...

Maybe without a batch/vb-script?

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

回答by dbenham

I'm sure it is possible to write a complex command that would list n levels of directories. But it would be hard to remember the syntax and error prone. It would also need to change each time you want to change the number of levels.

我确信可以编写一个复杂的命令来列出 n 级目录。但是很难记住语法并且容易出错。每次要更改级别数时,它也需要更改。

Much better to use a simple script.

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

EDIT 5 Years Later- Actually, there is a simple one liner that has been available since Vista. See my new ROBOCOPY solution.

5 年后编辑- 实际上,自 Vista 以来就有一个简单的衬里可用。查看我的新 ROBOCOPY 解决方案。

Here is a batch solution that performs a depth first listing. The DIR /S command performs a breadth first listing, but I prefer this depth first format.

这是一个执行深度优先列表的批处理解决方案。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

The breadth first version is nearly the same, except it requires an extra FOR loop.

广度优先版本几乎相同,只是它需要一个额外的 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

Both scripts expect two arguments:

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

arg1 = the path of the root directory to be listed

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

arg2 = the number of levels to list.

arg2 = 要列出的级别数。

So to list 3 levels of the current directory, you could use

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

listDirs.bat . 3

To list 5 levels of a different directory, you could use

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

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

回答by dbenham

After all this time (5 years), and I just now stumble on a simple command line one liner that has been available all along. ROBOCOPYhas been a standard Windows utility since Vista, and is available to XP via the Windows Resource Kit.

经过这么长时间(5 年),我刚刚偶然发现了一个简单的命令行,一个一直可用的 liner。ROBOCOPY自 Vista 以来,它一直是标准的 Windows 实用程序,可通过 Windows 资源工具包在 XP 中使用。

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

Explanation

解释

    /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.

The /lev:noption includes the root in the count, and you want 3 subdirectory levels, which is why I added 1 to the value.

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

Processing further

进一步加工

The output is not perfect in that the root folder is included in the output, and each path includes fixed width leading whitespace. You can conveniently eliminate the root path as well as the leading whitespace with FOR /F.

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

The ROBOCOPYoutput includes an initial blank line, which is why the skipmust be 2 instead of 1.

ROBOCOPY输出包括初始空白行,这就是为什么skip必须是2,而不是1。

Each path will end with \. I like that feature because it makes it obvious that we are listing folders and not files. If you really want to eliminate the trailing \, then you can add an extra FOR.

每条路径都以\. 我喜欢这个功能,因为很明显我们列出的是文件夹而不是文件。如果你真的想消除尾随\,那么你可以添加一个额外的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

But the command is becoming a bit ungainly to type. It should be easy to incorporate this technique into a utility batch file that takes the root path and level as arguments. You must remember to double the percents if you put the command within a batch script.

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

回答by elady

Here is a solution which based on the depth first listing solution of @dbenham,
and enables to set minimum levelas well.

这是一个基于@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

To set the minimum level just provide it as 3rd parameter.
For example: to list from level 2 to level 5, you could use

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

listDirs.bat target_path 5 2

Alternatively, you can list from the base level by leaving this parameter empty

或者,您可以通过将此参数留空来从基本级别列出

listDirs.bat target_path 5

回答by sancho.s ReinstateMonicaCellio

This is a little enhancement over the solution of dbenham (and elady). It indents output according to depth. It significantly increases readability.

这是对 dbenham(和 elady)的解决方案的一点改进。它根据深度缩进输出。 它显着提高了可读性

@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
set "indent=."
if %currentLevel% lss %maxLevel% (
  for /d %%F in (*) do (
    for /l %%i in (1,1,%currentLevel%) do echo|set /p=%indent%
    if %currentLevel% geq %minLevel% echo %%~fF
    set /a currentLevel+=1
    call :procFolder "%%F"
    set /a currentLevel-=1
  )
)
popd

One can set the indentation character in set "indent ...

一个可以设置缩进字符 set "indent ...