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