2017-06-04 10 views
0

パスのすべてのファイルのハッシュを(再帰的に)識別するスクリプトを実行しています。これは大丈夫です。powershellでハッシュを比較して同じハッシュのファイルを削除しようとしています

ハッシュが同じであることを特定した後、それらを配列に保存したいので、同じハッシュを持つこれらのファイルを削除できます。重複ファイル。そして、私は午後と夕方になってそれをどうやって行うのか考えようとしています。現時点では マイコード:

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 
[email protected]() 
[email protected]() 

#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 

} 

だから、最後の部分「$コピー+ = $重複が」正常に動作しません。

私は最初のファイルを「元の」配列に保存することを考えていました。 2番目のハッシュが同じハッシュの場合は、2番目を「コピー」配列に保存します。しかし、私はハッシュを取得するときに私はスクリプトの第1部でそれを行うことができますか分からない。

その後、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". 
+0

したがって、実際には重複を削除することができます。なぜなら、ハッシュと重複を「オブジェクト」として使用しているからです。私の場合は、検索を再帰的に行います(すべてのファイルとディレクトリのファイルなどを取得します)。私はそれを試してみましたが、それは再帰的なことではありませんので、再帰的な部分を追加するだけかもしれません。 私も "最初のものを除いてすべての重複を削除"しようとしましたが、実際のファイルは削除されません! また、「複製」は配列です、そうですか? –

+0

はい、 'Recurse'パラメータが必要です。私はそれを使わずにテストしていましたが、追加するのを忘れてしまいました。コードを実行するとエラーメッセージが表示されますか? – Bluecakes

+0

これはファイルを削除したと言われていますが、ディレクトリに移動してファイルが削除されたかどうかを調べるときに、メッセージ彼らはされているが、彼らはそうではないことが飛び出す。 –

2

「最初以外のすべての重複を削除し、」コメントを解除場合、私は、上記のコマンドから受け取る出力されます。私はそれをして、私は重複ファイルの1つだけの項目とすべての重複したファイルを持つリストとのリストを持っています。あなたが代わりにSHA1アルゴリズムを使用することができます

MD5

SHA1はMD5アルゴリズムをさがすルートフォルダに

$myFilePath = '' 
を設定

$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 

よりもはるかに高速であります

+0

ありがとう!それは素晴らしい作品です!どのようにして、配列内のすべてのファイルを削除するのですか?配列や配列内の要素を削除するのではなく、実際のファイルを削除します。 –

+0

$ doubledItems | %{Remove-Item $ _。path} – k7s5a

関連する問題