我编写了一个脚本来帮助我识别重复的文件。由于某种原因,如果我拆分这些命令并导出/导入到 CSV,它的运行速度比将所有内容都保留在内存中要快得多。这是我的原始代码,速度慢得可怕:
Get-ChildItem M:\ -recurse | where-object {$_.length -gt 524288000} | select-object Directory, Name | Group-Object directory | ?{$_.count -gt 1} | %{$_.Group} | export-csv -notypeinformation M:\Misc\Scripts\Duplicates.csv
如果我将其分成 2 个命令并在中间导出到 CSV,则运行速度会快 100 倍。我希望有人能够阐明我做错了什么。
Get-ChildItem M:\ -recurse | where-object {$_.length -gt 524288000} | select-object Directory, Name | Export-Csv -notypeinformation M:\Misc\Scripts\DuplicateMovies\4.csv
import-csv M:\Misc\Scripts\Duplicates\4.csv | Group-Object directory | ?{$_.count -gt 1} | %{$_.Group} | export-csv -notypeinformation M:\Misc\Scripts\Duplicates\Duplicates.csv
remove-item M:\Misc\Scripts\Duplicates\4.csv
感谢任何建议,
~TJ
最佳答案
这不是Group-Object
太慢了,这是你的分组条件,你要求它分组FileInfo
对象 .Directory
property代表其父文件夹 DirectoryInfo
实例。因此,您要求 cmdlet 按非常复杂的对象作为分组条件对对象进行分组,您可以使用 .DirectoryName
property作为分组条件,它代表父目录的 FullName
属性(一个简单的字符串),或者您可以使用 .Directory.Name
property它代表父文件夹Name
(也是一个简单的字符串)。
总而言之,在这种情况下导出到 CSV 速度更快的主要原因是因为当 Export-Csv
时从管道接收对象时,它会对每个对象的属性值调用 ToString()
方法,因此 Directory
实例会转换为其字符串表示形式(调用 ToString()
to this instance ends up being the folder's FullName
)。
对于你的代码,如果你想保持尽可能高效而不使其过于复杂:
Get-ChildItem M:\ -Recurse -File | & {
process {
if($_.Length -gt 500mb) { $_ }
}
} | Group-Object DirectoryName | & {
process {
if($_.Count -gt 2) {
foreach($object in $_.Group) {
[pscustomobject]@{
Directory = $_.Name # => This is the Parent Directory FullName
Name = $object.Name
}
}
}
}
} | Export-Csv M:\Misc\Scripts\Duplicates\4.csv -NoTypeInformation
如果您想按父Name
而不是FullName
对它们进行分组,您可以使用:
Group-Object { $_.Directory.Name }
关于PowerShell - 组对象性能不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74117863/