下記環境下で、forfilesコマンドをいろいろ試験してみました。
環境をpowershellで即興で作るコマンド↓
https://qiita.com/kashiwagi0910/items/306a02e378a261114e2d
test/
├FOLDER_1/
│ └FORDER_A/
│ │ └text_a.txt
│ │ └text_b.txt
│ │ └text_c.txt
│ └FORDER_B/
│ └FORDER_C/
│ └text_A.txt
│ └text_B.txt
│ └text_C.txt
├FOLDER_2/
├FOLDER_3/
└text_1.txt
└text_2.txt
└text_3.txt
カレントディレクトリ:test/ にて
とりあえずコマンド打っていきます。
>forfiles
"FOLDER_1"
"text_1.txt"
"text_2.txt"
"text_3.txt"
FOLDER_1/の配下は表示されないですね!
/sオプションをつけてみます。
>forfiles /s
"FOLDER_1"
"FOLDER_2"
"FOLDER_3"
"text_1.txt"
"text_2.txt"
"text_3.txt"
"FOLDER_A"
"FOLDER_B"
"FOLDER_C"
"text_A.txt"
"text_B.txt"
"text_C.txt"
"text_a.txt"
"text_b.txt"
"text_c.txt"
確かに FOLDER_1/ の配下の FOLDER_A の配下まで全部表示できました!
/c オプションでコマンドを付与できるみたいですが、デフォルトは
"cmd /c echo @file"
とファイル名だけを表示させる様です。
ファイルの更新日は@fdateという変数に格納されるようです。
ファイルのパス(今回は相対パス)は@relpathという変数に格納されるようです。
いろいろ表示させてみましょう。
>forfiles /s /c "cmd /c echo @relpath 最終更新日:@fdate"
".\FOLDER_1" 最終更新日:2020/06/25
".\FOLDER_2" 最終更新日:2020/07/25
".\FOLDER_3" 最終更新日:2020/08/25
".\text_1.txt" 最終更新日:2020/06/25
".\text_2.txt" 最終更新日:2020/07/25
".\text_3.txt" 最終更新日:2020/08/25
".\FOLDER_1\FOLDER_A" 最終更新日:2020/06/25
".\FOLDER_1\FOLDER_B" 最終更新日:2020/07/25
".\FOLDER_1\FOLDER_C" 最終更新日:2020/08/25
".\FOLDER_1\text_A.txt" 最終更新日:2020/06/25
".\FOLDER_1\text_B.txt" 最終更新日:2020/07/25
".\FOLDER_1\text_C.txt" 最終更新日:2020/08/25
".\FOLDER_1\FOLDER_A\text_a.txt" 最終更新日:2020/06/25
".\FOLDER_1\FOLDER_A\text_b.txt" 最終更新日:2020/07/25
".\FOLDER_1\FOLDER_A\text_c.txt" 最終更新日:2020/08/25
オッケー!
続いて、n日以上前のデータを抽出してみます。
/d オプションに 数値やyyyymmddを入れると最終更新日付で抽出できるみたいです。
50日以上前なら /d -50ですね
>forfiles /s /d -50
"FOLDER_1"
"text_1.txt"
"FOLDER_A"
"text_A.txt"
"text_a.txt"
オッケー!
次はデータの削除をします。
50日以前のデータを削除してみましょう。
フォルダの削除は rmdir コマンドですね。
>forfiles /s /d -50 /c "cmd /c rmdir @file"
ディレクトリが空ではありません。
ディレクトリ名が無効です。
ディレクトリが空ではありません。
ディレクトリ名が無効です。
ディレクトリ名が無効です。
一部エラーが起こりました。
とりあえず、このやり方(rmdir でオプションを何もつけない)だと
・ファイルは消せない
・空のディレクトリは消せない
ということですね。
rmdir に /s オプションをつけると、中身まで丸ごと削除できるみたいです。
>forfiles /s /c "cmd /c rmdir /s @file"
FOLDER_1、よろしいですか (Y/N)? Y
FOLDER_2、よろしいですか (Y/N)? Y
FOLDER_3、よろしいですか (Y/N)? Y
text_1.txt、よろしいですか (Y/N)? Y
ディレクトリ名が無効です。
text_2.txt、よろしいですか (Y/N)? Y
ディレクトリ名が無効です。
text_3.txt、よろしいですか (Y/N)? Y
ディレクトリ名が無効です。
エラー: 指定されたファイルが見つかりません。
エラー: 指定されたファイルが見つかりません。
エラー: 指定されたファイルが見つかりません。
中身のファイルを削除してよいかどうか聞いてくれていますね。
さらに /q オプションで、いちいち確認しなくても全部削除してくれます。
使うときはもちろん注意が必要ですね。
rmdirの動作は確認できましたので、一旦ファイル、フォルダを復元しました。
次は、delコマンドの動作を試しました。
>forfiles /s /d -50 /c "cmd /c del @file""
C:\Users\t.kashiwagi.LOCAL\Desktop\test\FOLDER_1\*、よろしいですか (Y/N)? Y
C:\Users\t.kashiwagi.LOCAL\Desktop\test\FOLDER_1\FOLDER_A\*、よろしいですか (Y/N)? Y
削除してよいかどうかの確認がでましたね。
このままYすると、該当したフォルダ(今回でいうならtest\FOLDER_1)の配下のファイルは、更新日時が50日に至っていないファイルまで全て削除してしまう模様です。
↓これとか
".\FOLDER_1\FOLDER_A\text_c.txt" 最終更新日:2020/08/25
Y
逆にNすると、配下のファイルの更新日時が50日を超えているかどうか1つ1つ確認し、50日を超えていないファイルを残してくれます。
あるファイルを削除すると、そのファイルを格納していたフォルダの更新日時も変わります。
50日以前のデータを削除する、となった場合
①フォルダを削除する。(フォルダの更新日時が古ければ問答無用で削除)
forfiles /s /d -50 /c "cmd /c rmdir /s /q @file"
②ファイルを削除する。
forfiles /s /d -50 /c "cmd /c del @file"
の2段階処理の形がよいかもしれません。
/p オプションで 開始するディレクトリも指定できます。
バッチファイルを作成するときはこんな感じになりますね。
FORFILES /p C:\Users\hogehoge\Documents\ /s /d -50 /c "cmd /c rmdir /s /q @file"
FORFILES /p C:\Users\hogehoge\Documents\ /s /d -50 /c "cmd /c del @file"
※ちなみに /pオプションについて、ネットワーク上のUNCパスは通常では使えません。
pushdコマンドで移動する手順が必要になります。