Hatena::ブログ(Diary)

IIJIMASの日記 RSSフィード

2010-11-01

指定した名前のディレクトリを再帰的に削除するコマンドライン

以下のようなツリーのディレクトリ(フォルダ)がある場合に「target」ディレクトリを一括で削除したいとします。

├─A
│  ├─AA
│  │  ├─AAA
│  │  │  └─target
│  │  ├─AAB
│  │  │  └─target
│  │  └─target
│  ├─AB
│  │  └─target
│  └─target
├─B
│  ├─BA
│  │  └─target
│  └─target
└─target

さてどうすればいいでしょう?

Windowsコマンドにはファイルを削除するコマンドにdelがあります。

del /?

DEL [/P] [/F] [/S] [/Q] [/A[[:]属性]] 名前
ERASE [/P] [/F] [/S] [/Q] [/A[[:]属性]] 名前

  名前          ファイルまたはディレクトリ (複数可) の一覧を指定します。
                複数のファイルを削除するときはワイルドカードを使用します。
                ディレクトリが指定されたときはディレクトリ内のすべてのファ
                イルは削除されます。

  /P            各ファイルを削除する前に確認のメッセージを表示します。
  /F            読み取り専用ファイルを強制的に削除します。
  /S            指定されたファイルをすべてのサブディレクトリから削除します。
  /Q            ワイルドカードを使用して一括削除するときに、確認のメッセージ
                を表示しません。(QUIET モード)
  /A            属性により削除するファイルを選択します。
  属性          R  読み取り専用            S  システム ファイル
                H  隠しファイル            A  アーカイブ
                I  非インデックス対象ファイル  L  再解析ポイント
                -  その属性以外

コマンド拡張機能を有効にすると、DEL と ERASE は次のように変更されます:

/S スイッチの表示形式が逆になり、見つからなかったファイルではなく
削除されたファイルだけが表示されるようになります。

delコマンドではワイルドカード(*)を使って複数のファイルを削除できます。

たとえば、tree /fコマンドで以下のようになっているとしましょう。

C:\test>tree /f
│  xxx.txt
│
├─A
│  │  xxx.txt
│  │
│  ├─AA
│  │  │  xxx.txt
│  │  │
│  │  ├─AAA
│  │  │  │  xxx.txt
│  │  │  │
│  │  │  └─target
│  │  ├─AAB
│  │  │  │  xxx.txt
│  │  │  │
│  │  │  └─target
│  │  └─target
│  ├─AB
│  │  │  xxx.txt
│  │  │
│  │  └─target
│  └─target
├─B
│  │  xxx.txt
│  │
│  ├─BA
│  │  │  xxx.txt
│  │  │
│  │  └─target
│  └─target
└─target
ここで、delコマンドを実行すると、
C:\test>del /F /S /Q *xxx.txt
削除したファイル - C:\test\xxx.txt
削除したファイル - C:\test\A\xxx.txt
削除したファイル - C:\test\A\AA\xxx.txt
削除したファイル - C:\test\A\AA\AAA\xxx.txt
削除したファイル - C:\test\A\AA\AAB\xxx.txt
削除したファイル - C:\test\A\AB\xxx.txt
削除したファイル - C:\test\B\xxx.txt
削除したファイル - C:\test\B\BA\xxx.txt

C:\test>tree /f
├─A
│  ├─AA
│  │  ├─AAA
│  │  │  └─target
│  │  ├─AAB
│  │  │  └─target
│  │  └─target
│  ├─AB
│  │  └─target
│  └─target
├─B
│  ├─BA
│  │  └─target
│  └─target
└─target

となります。

同じように、targetディレクトリを一掃しようと実行してみると…

C:\test>del /F /S /Q *target

C:\test>tree /f
C:.
├─A
│  ├─AA
│  │  ├─AAA
│  │  │  └─target
│  │  ├─AAB
│  │  │  └─target
│  │  └─target
│  ├─AB
│  │  └─target
│  └─target
├─B
│  ├─BA
│  │  └─target
│  └─target
└─target

残念ながらdelコマンドではディレクトリは削除できません。引数ディレクトリを指定できますがその中身のファイルを削除できるだけです。

ディレクトリを削除するコマンドとしてrmdirまたはrdがあります。

rmdir /?

RMDIR [/S] [/Q] [ドライブ:]パス
RD [/S] [/Q] [ドライブ:]パス

    /S      指定されたディレクトリに加えて、そのディレクトリ内のすべての
            ディレクトリとファイルを削除します。ディレクトリ ツリーを削除
            するときに使用します。

    /Q      /S を指定してディレクトリ ツリーを削除するときに、確認の
            メッセージを表示しません。(QUIET モード)

目的のように、targetディレクトリを削除しようとしてdelと同じように使おうとすると、

C:\test>rmdir /S /Q *target
ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。

となってしまいます。rmdirコマンドはワイルドカードは使えません。また、delやrmdirヘルプを見るかぎり目的を達成できそうなオプションはありません。

実は、ループを扱うコマンドのforが使用できます。

for /?の一部

FOR /R [[ドライブ:]パス] %変数 IN (セット) DO コマンド [コマンド パラメーター]

    [ドライブ:]パスから始めて、ツリーの各ディレクトリで FOR 文を実行し
    ます。/R の後にディレクトリが指定されていない場合は、現在の
    ディレクトリが使用されます。セットが単一のピリオド (.) である場合は、
    ディレクトリ ツリーの列挙だけを行います。

これを使って、以下のようにすれば目的を達成できます。

for /R %d in (フォルダ名) do rmdir /S /Q "%d"

実際、

C:\test>for /R %d in (target) do rmdir /S /Q "%d"

C:\test>rmdir /S /Q "C:\test\target"

C:\test>rmdir /S /Q "C:\test\A\target"

C:\test>rmdir /S /Q "C:\test\A\AA\target"

C:\test>rmdir /S /Q "C:\test\A\AA\AAA\target"

C:\test>rmdir /S /Q "C:\test\A\AA\AAB\target"

C:\test>rmdir /S /Q "C:\test\A\AB\target"

C:\test>rmdir /S /Q "C:\test\B\target"

C:\test>rmdir /S /Q "C:\test\B\BA\target"

C:\test>tree
C:.
├─A
│  ├─AA
│  │  ├─AAA
│  │  └─AAB
│  └─AB
└─B
    └─BA

となります。

もちろん、走査先のディレクトリに指定したディレクトリがなければ

指定されたファイルが見つかりません。

というメッセージが表示されますが、副作用はありませんので問題ありません。

TortoiseSVNを使っているときに、作業ディレクトリに.svnディレクトリができます。それをディレクトリをごとメディアにコピーなど、コピーして別の目的に使用したい場合があります。その場合は、エクスポートするのが正しいのですが、そうしなかった場合に、コピー先では不要な.svnディレクトリもコピーされてしまいます。

この時コピー先で、

for /R %d in (.svn) do rmdir /S /Q "%d"

を使用すると.svnを一掃することができます。

pp 2015/11/08 05:19 これじゃ動かない。for の /D オプションが抜けてる。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/IIJIMAS/20101101/1288537836