我正在编写一个脚本,用于标识路径的所有文件的哈希值(并递归地)。没关系。
当我确定哪些哈希是相同的,我想将它们保存到一个数组中以便稍后我可以删除这些具有相同哈希值的文件(如果我想),或者只是打印副本时,我的问题就来了文件。我整个下午和晚上一直试图弄清楚如何去做。 我的代码目前:
Write-Host "Write a path: "
$UserInput=Read-Host
Get-ChildItem -Path $UserInput -Recurse
#Get-FileHash cmdlet to get the hashes
$files = Get-ChildItem -Path $UserInput -Recurse | where { !$_.PSIsContainer }
$files | % {(Get-FileHash -Path $_.FullName -Algorithm MD5)}
#Creating an array for all the values and an array for the duplicates
$originals=@()
$copies=@()
#grouping the hashes that are duplicated cmdlet Group-Object:
$Duplicates = Get-ChildItem -Path $UserInput -Recurse -File |Group {($_|Get-FileHash).Hash} |Where Count -gt 1
foreach($FileGroup in $Duplicates)
{
Write-Host "These files share hash : $($FileGroup.Name)"
$FileGroup.Group.FullName |Write-Host
$copies+=$Duplicates
}
所以最后一部分“$ copies + = $ Duplicates”无效。
在开始时我正在考虑将第一个文件保存在“原始”数组中。如果第二个具有相同的散列,则在“副本”数组中保存第二个。但是我不确定在获取哈希值时是否可以在剧本的第一部分中这样做。
之后,第二个数组将具有重复项,因此很容易从计算机中删除它们。
答案 0 :(得分:2)
我认为你应该过滤这些物品。我做了它,我有一个列表,只有一项重复文件和一个包含所有重复文件的列表。
您可以使用 SHA1 算法代替 MD5
SHA1比MD5算法快得多
$fileHashes = Get-ChildItem -Path $myFilePath -Recurse -File | Get-Filehash -Algorithm SHA1
$duplicates = $fileHashes | Group hash | ? {$_.count -gt 1} | % {$_.Group}
$uniqueItems = @{}
$doubledItems = @()
foreach($item in $duplicates) {
if(-not $uniqueItems.ContainsKey($item.Hash)){
$uniqueItems.Add($item.Hash,$item)
}else{
$doubledItems += $item
}
}
# all duplicates files
$doubledItems
# Remove the duplicate files
# $doubledItems | % {Remove-Item $_.path} -Verbose
# one of the duplicate files
$uniqueItems
设置搜索根文件夹
$myFilePath = ''
答案 1 :(得分:1)
您只需要使用Get-ChildItem
一次,一旦拥有了所有文件,就可以为它们创建哈希值,然后将哈希值分组以查找重复项。请参阅下面的示例代码:
Write-Host "Write a path: "
$UserInput=Read-Host
#Get-FileHash cmdlet to get the hashes
$files = Get-ChildItem -Path $UserInput -Recurse | Where-Object -FilterScript { !$_.PSIsContainer }
$hashes = $files | ForEach-Object -Process {Get-FileHash -Path $_.FullName -Algorithm MD5}
$duplicates = $hashes | Group-Object -Property Hash | Where-Object -FilterScript {$_.Count -gt 1}
foreach($duplicate in $duplicates)
{
Write-Host -Object "These files share hash : $($duplicate.Group.Path -join ', ')"
# delete first duplicate
# Remove-Item -Path $duplicate.Group[0].Path -Force -WhatIf
# delete second duplicate
# Remove-Item -Path $duplicate.Group[1].Path -Force -WhatIf
# delete all duplicates except the first
# foreach($duplicatePath in ($duplicate.Group.Path | Select-Object -Skip 1))
# {
# Remove-Item -Path $duplicatePath -Force -WhatIf
# }
}
取消注释最后的代码,根据您的偏好删除重复项,当您准备删除文件时,请务必删除-WhatIf
参数。
这是我从上述命令收到的输出,如果我取消注释"删除除第一个"
之外的所有重复项Write a path:
H:\
These files share hash : H:\Rename template 2.csv, H:\Rename template.csv
What if: Performing the operation "Remove File" on target "H:\Rename template.csv".