
私が実行しているコマンドはforfiles -p"C:\testdata" -m*.* -d-1 -c"cmd /c echo @PATH\@FILE"
1 日前のファイルのみをリストするように指定しましたが、ステートメントを実行すると、今日作成されたファイルのリストが返されます。
それはなぜでしょうか? 何か間違っているのでしょうか? 日付ではなく、たとえば 24 時間などの期間を指定したほうがよいでしょうか?
私が持っている forfiles のバージョンは次のとおりです。バッチ ファイルは Windows XP で実行されています。FORFILES v 1.1 - [email protected] - 4/98
答え1
Forfiles
使用しているバージョンは、ネイティブの XP コマンドではありません。これは、ユーティリティの古いバージョンであり、元々はW2K Resource Kits
(確かではありませんが、NT リソース キットにまで含まれていたと思います) 配布されていました。XP でそれを使用すること自体に問題はありませんが、構文をよく見ると、次のように書かれています (強調は筆者による):
-d[+|-][DDMMYY|DD] 日付がDDMMYY以上または以下であるファイルを選択(UTC) または日付が >= または <= (現在の日付 - DD 日) のファイル
注記UTC説明にあります。これは、(1.1) forfiles
システム時間が UTC (オフセットなし)、夏時間でない限り、あなたが考えているのとは異なるタイムスタンプを使用することを意味します。
これはおそらく例を見れば簡単でしょう。私は UTC+1、夏時間です。
(今日の日付 - 2012-09-19)
- ファイルを作成し、ディレクトリを実行します:
2012-09-19 00:14 5 zzz_utc.txt
今日の日付なので、forfiles によって選択されないはずです。確認してみましょう。
FORFILES -pc:\temp -mzzz_utc.* -d-1 -c"CMD /C Echo @FILE"
zzz_utc.txt
しかし、選択されます。なぜでしょうか? ファイルの UTC 時刻を見てみましょう (PowerShell から次のコマンドを実行します):
ls .\zzz_utc.txt |select LastAccessTime,LastAccessTimeUTC
LastAccessTime LastAccessTimeUtc
-------------- -----------------
2012-09-19 00:15:11 2012-09-18 22:15:11
ご覧のように、時刻UTC- が使用したものは(1.1) forfiles
昨日のものです! そのため、ツールによって選択されます。
答え2
「... 1 日前のファイルのみをリストしたいのですが...」
「昨日作成されたファイル」という意味ですか? つまり、(今日は 9 月 18 日)、変更日時が 9 月 17 日の午前 0000 (早朝の真夜中) 以上、9 月 17 日の末日の真夜中 (深夜) 以下であるファイルです。つまり、日付/時刻の制約が 2 つあり、forfiles
1 つ以上を指定することはできません。結論:forfiles
そうはならないと思います。
... ただし、Windows 7 ボックスで試してみると/d -1
、昨日またはそれ以前に作成されたファイルが表示されます。したがって、Windows XP バージョンがforfiles
壊れている可能性があります。
答え3
から優れたドキュメント(強調は筆者による):
最終更新日が現在の日付に指定した日数を加えた日付以降 (+)、または現在の日付以前 (-) のファイルを選択します。指定された日数を引いた値。
編集:
おそらく、VBScript を試してみるといいでしょう:
Set args = WScript.Arguments.Named
Set fso = CreateObject("Scripting.FileSystemObject")
d = 0
p = "."
If args.Exists("?") Or args.Count = 0 Then
WScript.Echo "Usage: cscript " & WScript.ScriptName & " [/d:DAYS] [/p:PATH]"
WScript.Quit(0)
End If
If args.Exists("d") Then d = args("d")
If args.Exists("p") Then p = args("p")
refDate = DateAdd("d", d, Now)
TraverseFolders fso.GetFolder(p)
Sub TraverseFolders(fldr)
For Each f In fldr.Subfolders
TraverseFolders(f)
Next
For Each f In fldr.Files
If f.DateLastModified < refDate Then
WScript.StdOut.WriteLine f.Path
'f.Delete
End If
Next
End Sub
答え4
FORFILES /D -1 には Windows 8 および Windows Server 2008 R2 でもバグがあるようです (ギリシャの日付を使用するシステムでは動作しません - すべてのファイルを選択します)
上記のコメントで提案されているように %date% を解析することもできますが、たとえば Windows 8 では日付は最初に曜日名とスペース文字の 3 文字で表示され、その後に従来の日付形式が表示されることに注意してください。また、その日付はローカライズされた形式になりますが、FORFILES /D は forfiles /? に従って dd/MM/yyyy 形式の日付を期待します (少なくとも Win8 では)。
訂正: /D -dd が何をするかについて誤解があるようです (ネットで検索したところ、私だけでなく他の人もそう思っています)。どうやら、dd 日前のファイルではなく、dd 日よりも古いファイルを検索するようです。
したがって、FORFILES の /D +dd/MM/yyyy 構文を使用し、昨日の日付を渡して、昨日以降の日付を持つすべてのファイルを検索する必要があります。これを自動化するには、%date% を使用して、%date:~7,2%/%date:~4,2%/%date:~-4% などで解析します (ロケールに応じて日付部分の順序を変更する必要がある場合があります)。