10

powershell を使用したい重複ファイル (例として jar ファイル) が数千あります。

  1. ファイルシステムを再帰的に検索する
  2. 重複を見つけます(名前のみ、チェックサム方式、またはその両方で)
  3. 1 つを除いてすべての重複を削除します。

私はpowershellが初めてで、これを助けてくれるかもしれないPSの人々に投げかけています。

4

4 に答える 4

16

これを試して:

ls *.txt -recurse | get-filehash | group -property hash | where { $_.count -gt 1 } | % { $_.group | select -skip 1 } | del

から: http://n3wjack.net/2015/04/06/find-and-delete-duplicate-files-with-just-powershell/

于 2016-03-07T18:46:05.937 に答える
3

質問は古いですが、コンテンツに基づいてすべての重複ファイルをクリーンアップする必要がありました。アイデアは単純ですが、このためのアルゴリズムは簡単ではありません。これは、重複を削除する「パス」のパラメーターを受け入れるコードです。

 Function Delete-Duplicates {
    param(
    [Parameter(
    Mandatory=$True,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True
    )]
    [string[]]$PathDuplicates)

    $DuplicatePaths = 
        Get-ChildItem $PathDuplicates | 
        Get-FileHash |
        Group-Object -Property Hash |
        Where-Object -Property Count -gt 1 |
        ForEach-Object {
            $_.Group.Path |
            Select -First ($_.Count -1)}
    $TotalCount = (Get-ChildItem $PathDuplicates).Count
 Write-Warning ("You are going to delete {0} files out of {1} total. Please confirm the prompt" -f $DuplicatePaths.Count, $TotalCount)    
 $DuplicatePaths | Remove-Item -Confirm

    }

スクリプト

a) すべての ChildItems を一覧表示します

b) それらから FileHash を取得します

c)ハッシュプロパティでそれらをグループ化します(したがって、すべての同じファイルが単一のグループに含まれます)

d) すでに固有のファイルを除外します (グループの数 -eq 1)

e)各グループをループし、最後のパスを除くすべてのパスをリストします-各「ハッシュ」の1つのファイルが常に残るようにします

f) 先行する前に、合計でいくつのファイルがあり、いくつのファイルが削除されるかを警告します。

おそらく最もパフォーマンス上のオプション (すべてのファイルを SHA1 で処理する) ではありませんが、ファイルが重複していることを保証します。私にとっては完璧に機能します:)

于 2014-12-19T12:47:41.123 に答える
3

ファイルの辞書を保持し、次のファイル名が以前に見つかった場合は削除します。

$dict = @{};
dir c:\admin -Recurse | foreach {
  $key = $_.Name #replace this with your checksum function
  $find = $dict[$key];
  if($find -ne $null) {
    #current file is a duplicate
    #Remove-Item -Path $_.FullName ?    
  }
  $dict[$key] = 0; #dummy placeholder to save memory
}

ファイル名をキーとして使用しましたが、必要に応じてチェックサムを使用できます (または両方) - コード コメントを参照してください。

于 2013-05-30T21:08:35.940 に答える
-1

重複ファイルを削除するだけでなく、ショートカットで置き換えることができます

#requires -version 3
<#
    .SYNOPSIS
    Script de nettoyage des doublons
    .DESCRIPTION
    Cherche les doublons par taille, compare leur CheckSum MD5 et les regroupes par Taille et MD5
    peut remplacer chacun des doubles par un lien vers le 1er fichier, l'original

    .PARAMETER Path
    Chemin ou rechercher les doublon

    .PARAMETER ReplaceByShortcut
    si specifier alors les doublons seront remplacé

    .PARAMETER MinLength
    ignore les fichiers inferieure a cette taille (en Octets)

    .EXAMPLE
    .\Clean-Duplicate '\\dfs.adds\donnees\commun'

    .EXAMPLE
    recherche les doublon de 10Ko et plus
    .\Clean-Duplicate '\\dfs.adds\donnees\commun' -MinLength 10000

    .EXAMPLE
    .\Clean-Duplicate '\\dpm1\d$\Coaxis\Logiciels' -ReplaceByShortcut
#>
[CmdletBinding()]
param (
    [string]$Path = '\\Contoso.adds\share$\path\data',
    [switch]$ReplaceByShortcut = $false,
    [int]$MinLength = 10*1024*1024 # 10 Mo
)

$version = '1.0'

function Create-ShortCut ($ShortcutPath, $shortCutName, $Target) {
    $link = "$ShortcutPath\$shortCutName.lnk"
    $WshShell = New-Object -ComObject WScript.Shell
    $Shortcut = $WshShell.CreateShortcut($link)
    $Shortcut.TargetPath = $Target
    #$Shortcut.Arguments ="shell32.dll,Control_RunDLL hotplug.dll"
    #$Shortcut.IconLocation = "hotplug.dll,0"
    $Shortcut.Description ="Copy Doublon"
    #$Shortcut.WorkingDirectory ="C:\Windows\System32"
    $Shortcut.Save()
    # write-host -fore Cyan $link -nonewline; write-host -fore Red ' >> ' -nonewline; write-host -fore Yellow $Target 
    return $link
}

function Replace-ByShortcut {
    Param(
        [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
            $SameItems
    )
    begin{
        $result = [pscustomobject][ordered]@{
            Replaced = @()
            Gain = 0
            Count = 0
        }
    }
    Process{
        $Original = $SameItems.group[0]
        foreach ($doublon in $SameItems.group) {
            if ($doublon -ne $Original) {
                $result.Replaced += [pscustomobject][ordered]@{
                    lnk = Create-Shortcut -ShortcutPath $doublon.DirectoryName -shortCutName $doublon.BaseName -Target $Original.FullName
                    target = $Original.FullName
                    size = $doublon.Length
                }
                $result.Gain += $doublon.Length
                $result.Count++
                Remove-item $doublon.FullName -force
            }
        }
    }
    End{
        $result
    }
}

function Get-MD5 {
    param (
        [Parameter(Mandatory)]
            [string]$Path
    )
    $HashAlgorithm = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
    $Stream = [System.IO.File]::OpenRead($Path)
    try {
        $HashByteArray = $HashAlgorithm.ComputeHash($Stream)
    } finally {
        $Stream.Dispose()
    }

    return [System.BitConverter]::ToString($HashByteArray).ToLowerInvariant() -replace '-',''
}

if (-not $Path) {
    if ((Get-Location).Provider.Name -ne 'FileSystem') {
        Write-Error 'Specify a file system path explicitly, or change the current location to a file system path.'
        return
    }
    $Path = (Get-Location).ProviderPath
}

$DuplicateFiles = Get-ChildItem -Path $Path -Recurse -File |
    Where-Object { $_.Length -gt $MinLength } |
        Group-Object -Property Length |
            Where-Object { $_.Count -gt 1 } |
                ForEach-Object {
                    $_.Group |
                        ForEach-Object {
                            $_ | Add-Member -MemberType NoteProperty -Name ContentHash -Value (Get-MD5 -Path $_.FullName)
                        }
                    $_.Group |
                        Group-Object -Property ContentHash |
                            Where-Object { $_.Count -gt 1 }
                }

$somme = ($DuplicateFiles.group | Measure-Object length -Sum).sum
write-host "$($DuplicateFiles.group.count) doublons, soit $($somme/1024/1024) Mo" -fore cyan

if ($ReplaceByShortcut) {
    $DuplicateFiles | Replace-ByShortcut
} else {
    $DuplicateFiles
}
于 2016-04-04T09:51:41.063 に答える