web-dev-qa-db-ja.com

DOSのdirコマンドの再帰的な深さを設定します

現在、次のコマンドを使用していくつかのディレクトリを一覧表示しています。

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

これにより、必要なリストがほぼ得られます。ただし、一部のフォルダーには非常に多くのサブフォルダーがあり、リストに表示したくないため、データが多すぎます。

コマンドの再帰の深さを-たとえば-3に制限することは可能ですか?

c:\dir_1\dir_2\dir_3\dir_foo

したがって、上記の例のc:>でコマンドを実行すると、dir_fooディレクトリは表示されませんが、dir_nディレクトリのみが表示されます...

たぶんバッチ/ vbスクリプトなしで?

15
Sauer

Nレベルのディレクトリを一覧表示する複雑なコマンドを作成することは可能だと確信しています。しかし、構文とエラーが発生しやすいことを覚えておくのは難しいでしょう。また、レベル数を変更するたびに変更する必要があります。

単純なスクリプトを使用する方がはるかに優れています。

5年後の編集-実際には、単純な1つのライナーがありますそれはVista以来利用可能です。 私の新しいROBOCOPYソリューションを参照してください。

これは、深さ優先リストを実行するバッチソリューションです。 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

どちらのスクリプトも2つの引数を想定しています。

arg1 =リストされるルートディレクトリのパス

arg2 =リストするレベルの数。

したがって、現在のディレクトリの3つのレベルを一覧表示するには、次を使用できます。

listDirs.bat . 3

異なるディレクトリの5つのレベルを一覧表示するには、次を使用できます。

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

結局のところ(5年)、私は今、ずっと利用可能であった1つのライナーを単純なコマンドラインで見つけました。 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は1ではなく2でなければなりません。

各パスは\で終わります。ファイルではなくフォルダを一覧表示していることが明らかになるので、この機能が気に入っています。末尾の\を本当に削除したい場合は、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倍にすることを忘れないでください。

9
dbenham

これは、@ 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
3
elady

これは、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

set "indent ...でインデント文字を設定できます