1. ホーム
  2. スクリプト・コラム
  3. DOS/BAT

フォルダ内のサブフォルダやファイルを一定時間ごとにすべて削除する方法

2022-01-25 18:37:05

Win9xの頃は、この問題は外部コマンドのdeltreeで簡単に解決できたのですが、windows2000やwindowsxp以降、このコマンドが廃止されてしまったので(本当に不思議です)、今はどう解決したらいいのでしょうか?del+rdで解決しようと思われるかもしれません。しかし、問題があります、それは、rdコマンドは指定したディレクトリを削除してしまうことです。例えば、現在のディレクトリ構成が以下のような場合です。
D:\>attrib /s /d d:\test*. *
A R I D:\test1.txt This file has read-only attribute
A H I D:\test2.txt This file has hidden attribute
A S I D:\test3.txt This file has system attribute
     H I D:\test101 このディレクトリは隠し属性を持っています。
A R I D:\test1.4.txt This file has read-only attribute
    S I D:\test1/2 このディレクトリにはシステム属性があります。
A R I D:\test12.5.txt This file has read-only attribute

一括処理の原則  このようにrd d: \testというコマンドを実行すると、rdはディレクトリtestをその内容とともに削除してしまいますが、ディレクトリtestは残しておきたいのです。では、どうすればいいのか?まずdelでd: \testディレクトリのファイルを削除し、次にrdでサブディレクトリを削除すればいいのです。このバッチ処理の内容は、以下の通りです。以下の内容を、deltree.bat のように、拡張子が .bat または .cmd のテキストファイルとして保存してください。
---この行を除いた場合
attrib -s -h -r %1**. * && del %1 Θ*. * /q
dir %1 /ad /b /s >del.txt 
for /f %%i in (del.txt) do rd %%i /s /q 
---この行を含めないでください ---。
そして、testディレクトリを削除する必要があるときは、次のように "deltree.bat d:\test" を実行するだけです(引用符は付けないでください)。

バッチの1行目  次に、バッチ1行目の%1は、バッチパラメータを読み込んで、次のようになります。 attrib -s -h -r d:\test**. * && del d:\test*. * /q
最初に attrib を使って test ディレクトリ内のすべてのファイルの属性を削除し、後で del がスムーズに実行されるようにします。
&& は結合記号で、前のコマンドを実行したときに、結合文字の後のコマンドを実行します。
delは、rdコマンドではtestディレクトリ以下のファイルを削除できないので、testディレクトリ以下のファイルをすべて削除します。さて、test以下のファイルが削除されたので、testディレクトリ以下のサブディレクトリの削除を開始します。

バッチ処理の2行目  2行目までバッチ実行すると、%1がバッチパラメータを読み込みます。これは、deltree d: \testの後に入力したもので、このdir d:\test /ad /b /s >del.txt になります。ここで、dirコマンドの後の各パラメータの意味は、以下のようになります。
 /AD 指定された属性のディレクトリを表示します。これにより、rd コマンドでこれらのディレクトリを後で削除することができます
/B 空のフォーマット(ヘッダー情報、サマリーなし)を使用します。dir コマンドは、" The volume in drive C has no label のような他の情報も出力するため、後の delete コマンドでのエラーを避けることができます。 ボリュームのシリアル番号は EE5B-D3AF" で、これは明らかに rd コマンドのエラーの原因となります。
/S 指定されたディレクトリとすべてのサブディレクトリにあるファイルを表示します。後で rd コマンドで簡単に削除できるように、ディレクトリとファイルへのフル パスを出力します。
このバッチ行を実行すると、カレントディレクトリにdel.txtファイルが生成されます。del.txtと入力し実行すると、以下のような出力が表示されます。
d:\test1 1
d:\test1.2
なぜテキストファイルに出力するのか?なぜdirの結果をrdに出力しないのですか?なぜなら、dirの結果は複数行になるので、一行ずつ書くと面倒ではないですか?また、将来、実際にバッチ処理を行う場合、対象フォルダの下にいくつサブディレクトリがあるかは予測できません。dirの結果をテキストファイルに出力して、それをrdに読ませれば便利じゃない?

3行目を一括処理  さて、削除するサブディレクトリのリストをテキストファイルdel.txtに出力しましたので、あとはrdコマンドでこれらのディレクトリを削除してください。しかし、rd自身は実際にはテキストファイルを読む機能を持っていないので、この問題を解決するためにforを使います。バッチ処理は最後の行まで実行されます: for /f %%i in (del.txt) do rd %%i /s /q 
%%i は for 文で使われているループ変数で、この変数が使われるたびに del.txt から一行が変数値として読み込まれ、この変数を do 実行に続くコマンドに渡すのが for の役割なので、ループを順次実行する for が形作るコマンドはこうなります。
最初のループ rd d:♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪
2回目のループ rd d:\test12 /s /q
gnaw0725 注:forループの詳細な説明については  https://www.jb51.net/article/31284.htm
ここでのrdパラメータの意味は、以下の通りです。
/S ディレクトリ自体だけでなく、指定されたディレクトリ以下のすべてのサブディレクトリとファ イルを削除します。ディレクトリ ツリーを削除するために使用します。
/Q /S と併用するクワイエットモード 確認を求めずにディレクトリ ツリーを削除します。

トラブルシューティング  なるほど、この場所に、バッチプロセスdeltree.batは、d: \test 以下のすべてのファイルとフォルダを、それらが持つ属性に関係なく削除するのですね。このバッチ処理で、例えばファイルが削除されないなどの問題が発生した場合、どのようにトラブルシュートすればよいのでしょうか?チェックポイントを2つ用意すればいいんです。
バッチのパラメータ取得は、パラメータ、つまり入力したターゲットフォルダを正しく取得しているかどうかを確認するもので、バッチの先頭に echo %1 を付けて、その結果を確認することができます。
エコー %1
attrib -s -h -r %1**. * && del %1 Θ*. * /q
gnaw0725 注:バッチは9つの引数を持つことができ、%0はバッチ自身、最初の引数%1、2番目の引数%2、......と続きます。
サブディレクトリの一覧はdel.txtとタイプして、正常ならd: \test 以下の全てのサブディレクトリが出力されるはずです。

スクリプトハウスエディタが追加されました。

実は、ファイルやフォルダーを削除するコマンドは、rdを使うとよりシンプルで残酷なものになります。

コピーコード コードは以下の通りです。

rd /s /q f:\ddd