目标:使用脚本运行 500 万到 1000 万个 XML 文件并评估它们的日期,如果超过 90 天,则删除该文件。该脚本将每天运行。

问题:使用 powershell Get-ChildItem -recurse,导致脚本锁定并且无法删除任何文件,我认为这是因为 Get-ChildItem 在对任何文件采取任何操作之前需要构建整个数组的方式。

解决方案?:经过大量研究,我发现 [System.IO.Directory]::EnumerateFiles 将能够在数组完全构建之前对数组中的项目采取行动,这样应该可以提高效率( https://msdn.microsoft.com/library/dd383458%28v=vs.100%29.aspx )。经过更多测试,我发现 foreach ($1 in $2)$1 | % {} 更有效
在我运行这个新代码并可能再次使该服务器崩溃之前,是否有任何人可以建议以更有效的方式编写脚本?

为了进行测试,我刚刚在 15,000 个目录中创建了 15,000 x 0.02KB txt 文件,其中包含随机数据并运行以下代码,我在 $date 变量上使用了 90 秒而不是 90 天,仅用于测试,删除所有文件花了 6 秒txt 文件。

$getfiles = [System.IO.Directory]::EnumerateFiles("C:\temp", "*.txt", "AllDirectories")
$date = ([System.DateTime]::Now).AddSeconds(-90)
foreach ($2 in $getfiles) {
if ([System.IO.File]::GetLastWriteTime($2) -le $date) {
[System.IO.File]::Delete($2)
} #if
} #foreach

最佳答案

Powershell one-liner 可处理 100,000 个 >= 90 天前的文件。

[IO.Directory]::EnumerateFiles("C:\FOLDER_WITH_FILES_TO_DELETE") |
select -first 100000 | where { [IO.File]::GetLastWriteTime($_) -lt
(Get-Date).AddDays(-90) } | foreach { rm $_ }

或显示进度:
[IO.Directory]::EnumerateFiles("C:\FOLDER_WITH_FILES_TO_DELETE") |
select -first 100000 | where { [IO.File]::GetLastWriteTime($_) -lt
(Get-Date).AddDays(-90) } | foreach { $c = 0 } { Write-Progress
-Activity "Delete Files" -CurrentOperation $_ -PercentComplete
((++$c/100000)*100); rm $_ }

这适用于包含大量文件的文件夹。感谢我的同事道格!

10-07 16:21
查看更多