PowerShell-组对象性能差



我编写了一个脚本来帮助我识别重复的文件。出于某种原因,如果我拆分这些命令并导出/导入到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:MiscScriptsDuplicates.csv

如果我把它分成两个命令,并在中间导出到CSV,它的运行速度大约快100倍。我希望有人能揭露我做错了什么。

Get-ChildItem M: -recurse | where-object {$_.length -gt 524288000} | select-object Directory, Name | Export-Csv -notypeinformation M:MiscScriptsDuplicateMovies4.csv
import-csv M:MiscScriptsDuplicates4.csv | Group-Object directory | ?{$_.count -gt 1} | %{$_.Group} | export-csv -notypeinformation M:MiscScriptsDuplicatesDuplicates.csv
remove-item M:MiscScriptsDuplicates4.csv

感谢任何建议,

~TJ

不是Group-Object,这是您的分组条件,您要求它根据代表其父文件夹DirectoryInfo实例的.Directory属性对FileInfo对象进行分组。因此,您要求cmdlet按一个非常复杂的对象对对象进行分组,作为分组条件,您可以使用.DirectoryName属性作为分组条件,它表示父目录的FullName属性(一个简单字符串(,也可以使用.Directory.Name属性,它代表父目录的文件夹Name(也是一个简单的字符串(。

总之,在这种情况下,导出到CSV更快的主要原因是,当Export-Csv从管道接收对象时,它会对每个对象的属性值调用ToString()方法,因此Directory实例会转换为其字符串表示形式(对此实例调用ToString()最终会成为文件夹的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:MiscScriptsDuplicates4.csv -NoTypeInformation

如果要按父Name而不是FullName对它们进行分组,可以使用:

Group-Object { $_.Directory.Name }

最新更新