用于删除不在进度条列表中的文件的Powershell脚本
我有一个文件夹,里面有.jpg文件。我将这些与access数据库中的产品相关联。产品的一个来源提供了这些.jpg文件,但它们不允许您仅轻松下载当前使用的图片。因此,我找到了一个PowerShell脚本来删除我不需要的文件用于删除不在进度条列表中的文件的Powershell脚本,powershell,progress-bar,delete-file,Powershell,Progress Bar,Delete File,我有一个文件夹,里面有.jpg文件。我将这些与access数据库中的产品相关联。产品的一个来源提供了这些.jpg文件,但它们不允许您仅轻松下载当前使用的图片。因此,我找到了一个PowerShell脚本来删除我不需要的文件 $exclusions = Get-Content C:\Users\office\Desktop\ExcludedPhotos.txt dir -rec M:\PhotoDirectory\PhotoFolder | Where-Object {$exclusions -no
$exclusions = Get-Content C:\Users\office\Desktop\ExcludedPhotos.txt
dir -rec M:\PhotoDirectory\PhotoFolder | Where-Object {$exclusions -notcontains $_.name } | Remove-Item
归功于@x0n
而且效果很好!但问题是这需要永远的时间,我有超过180000个项目需要搜索和删除。所以我想制作一个进度条,让我知道我在这个过程中走了多远
因此,经过一点搜索,我找到了一篇名为“使用进度条”的文章
问题是我不知道如何将两者混合在一起,但是我在这里做了一个尝试:
$exclusions = Get-Content C:\Users\office\Desktop\ExcludedPhotos.txt
1..100 | foreach-object {
Write-Progress -Activity "Deleting Files" -Status "$_ %" -Id 1 -PercentComplete $_ -CurrentOperation "Deleting File $_"
dir -rec M:\PhotoDirectory\PhotoFolder | Where-Object {$exclusions -notcontains $_.name } | Remove-Item
}
然而,这似乎比原始脚本要花更长的时间,我不知道它是如何工作的,我正在测试它,而我只需要删除10-15个文件
很可能我缺少了一些基本的东西,但我真的很感激有人能帮助我理解这一点
在这里,我添加了一个屏幕截图:
然而,这似乎比最初的剧本花费的时间更长
这是因为您尝试枚举、筛选和删除文件100次,这显然是不必要的 您要做的是计算删除文件的过程中的距离,然后将其作为传递给
写入进度
的百分比的基础。保持计数的最简单方法可能是使用常规的for
循环:
注意:前两个示例非常通用,请参阅底部的示例,其中考虑了您的卷(~180.000个文件)
另一个用来表示百分比的特征是删除的相对卷(总字节数)。我们只需跟踪需要删除的总字节数,以及到目前为止已删除的字节数,就可以做到这一点:
$exclusions = Get-Content C:\Users\office\Desktop\ExcludedPhotos.txt
$filesToDelete = Get-ChildItem M:\PhotoDirectory\PhotoFolder -Recurse | Where-Object {$exclusions -notcontains $_.Name }
$TotalSize = ($filesToDelete |Measure-Object -Property Length -Sum).Sum
$BytesRemoved = 0
foreach($file in $filesToDelete){
$percentage = $BytesRemoved / $TotalSize * 100
Write-Progress -Activity "Deleting Files" -Status "Deleted $BytesRemoved/$TotalSize bytes" -PercentComplete $percentage
$file |Remove-Item
$BytesRemoved += $file.Length
}
Write-Progress -Activity "Deleting Files" -Completed
正如@MatthewWetmore所指出的,每次删除文件时调用
Write Progress
当然会产生一些开销。对于180.000个文件,当进度从3.56325%提高到3.56331%时,您可能对UI更新不感兴趣
您可以使用for
循环以1%的增量计算整个项目集,然后在每次迭代中删除整个范围的文件:
[int]$hundredthStep = $filesToDelete.Count / 100
for($i = 0; $i -lt $filesToDelete.Count; $i += $hundredthStep){
# calculate progress percentage
$percentage = ($i + 1) / $filesToDelete.Count * 100
Write-Progress -Activity "Deleting Files" -Status "Deleting File up to #$($i+1)/$($filesToDelete.Count)" -PercentComplete $percentage
# delete file
$filesToDelete[$i..($i + $hundredthStep - 1)] |Remove-Item
}
# All done
Write-Progress -Activity "Deleting Files" -Completed
您希望执行类似的操作(请注意,这是未经测试的,因此我已将
-whatif
放在remove cmdlet上,当您满意它正常工作时,应该将其删除):
如果要删除的文件数非常高,他还将受益于不使用每个文件而是每隔几个文件写入进度。例如,将计数除以100,四舍五入到最接近的整数,然后将其用作计数器的模数。例如,对于1-100个文件,您将写入每个文件的进度。200,每隔一个文件。对于1000,每10个…另外,我看到一个非常大的树上的递归get项非常慢。我在获取item-recurse-directory,然后迭代获取item-file方面运气更好。我在这方面写了一些变体,用于验证OS VHD或WIM内容。“这是因为您尝试枚举、筛选和删除文件100次,这显然是不必要的。”这是有道理的,当然,这将需要更长的时间,因为我正试图让它在整个脚本中运行100次,并给自己一个进度条,告诉我什么时候完成重复自己。我喜欢这个选项,它计算删除的总字节数。“我要试试看,然后带着我的发现回来。”马修维特莫尔说得很好,他用第一个例子计算了1%increments@MatthewWetmore同样有效,但执行循环体180000次,而不是100次:-)
[int]$hundredthStep = $filesToDelete.Count / 100
for($i = 0; $i -lt $filesToDelete.Count; $i += $hundredthStep){
# calculate progress percentage
$percentage = ($i + 1) / $filesToDelete.Count * 100
Write-Progress -Activity "Deleting Files" -Status "Deleting File up to #$($i+1)/$($filesToDelete.Count)" -PercentComplete $percentage
# delete file
$filesToDelete[$i..($i + $hundredthStep - 1)] |Remove-Item
}
# All done
Write-Progress -Activity "Deleting Files" -Completed
$exclusions = Get-Content C:\Users\office\Desktop\ExcludedPhotos.txt
$files = dir -rec M:\PhotoDirectory\PhotoFolder | Where-Object {$exclusions -notcontains $_.name }
$files | foreach-object {
$num += 1
Write-Progress -Activity "Deleting Files" -Status "$_ %" -Id 1 -PercentComplete (($num / $files.count) * 100) -CurrentOperation "Deleting File $($_.name)"
$_ | Remove-Item -WhatIf
}