在PowerShell中使用相同散列比较散列和删除文件不起作用

问题描述 投票:0回答:2

我正在做一个脚本,用于标识路径的所有文件的哈希值(并递归)。这没关系。

我的问题来了,在我确定哪些哈希是相同的之后,我想将它们保存到一个数组中以便稍后我可以删除这些具有相同哈希值的文件(如果我想),或者只打印重复文件。我整个下午和晚上一直试图弄清楚如何去做。我的代码目前:

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”无法正常工作。

在开始时,我正在考虑将第一个文件保存在“原始”数组中。如果第二个具有相同的散列,则在“副本”数组中保存第二个。但是我不确定在获取哈希时我是否可以在剧本的第一部分中这样做。

之后,第二个数组将具有重复项,因此很容易从计算机中删除它们。

powershell hash
2个回答
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".

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 = ''
© www.soinside.com 2019 - 2024. All rights reserved.