Windows で、ファイル名ではなくコンテンツによって判別され、あるフォルダには存在するが別のフォルダには存在しないファイルのリストを取得します。

Windows で、ファイル名ではなくコンテンツによって判別され、あるフォルダには存在するが別のフォルダには存在しないファイルのリストを取得します。

2 つのディレクトリ (DirA と DirB) がある場合、DirA に存在するが DirB には存在しないファイルのリストを検索する最も効率的な方法は何ですか?

私はツールを使用してこれを実行しようとしましたjdupes.exe --printunique --recurse -Oが、DirA に上記のファイルの重複が存在する場合、上記の基準を満たすファイルが除外されるという副作用があります。

ファイルは DirA と DirB の完全に異なるサブディレクトリにあり、名前も異なる場合があります。したがって、ファイルの内容だけが永続的な特性となります。

答え1

返された文字列パワーシェル取得-ファイルハッシュの鍵として使用できますハッシュ表コンテンツを完全修飾パスに関連付けます。このコードは、次の注意事項に従って、各パスのハッシュテーブルを作成します。

  • すべての空のファイルのコンテンツ ハッシュは同一であるため、空のファイルは無視されます。(各ディレクトリで見つかった空のファイルのリストを作成することもできます)
  • 重複が見つかった場合内でインデックスを作成するディレクトリでは、最初に見つかったファイルのみがテーブルに追加されます$HashOut$Dupsテーブルには、同一のコンテンツを共有するすべてのパスのリストが含まれます。

パワーシェル:

Function Get-DirHash ( [String]$PathIn , [PSObject]$HashOut )
{
    $HashOut.Clear()
    gci $PathIn *.txt -Recurse | ? Length -gt 0 | Get-FileHash | %{
        If ( $HashOut.Contains($_.Hash) )
        {
            If ( $Dups.Contains($_.Hash) )
            {
                $Dups[$_.Hash] += $_.Path
            }
            Else
            {
                $Dups.Add( $_.Hash , @( $HashOut[$_.Hash] , $_.Path ))
            }
        }
        Else
        {
            $HashOut.Add( $_.Hash , $_.Path )
        }
    }
}

$DirA     = 'c:\whatever'
$DirB     = 'c:\whenever'
$TableA   = @{}
$TableB   = @{}
$Dups     = @{}
$Unique2A = New-Object System.Collections.Generic.List[String]

Get-DirHash -PathIn $DirA -HashOut $TableA
Get-DirHash -PathIn $DirB -HashOut $TableB

$TableA.Keys | %{
    If ( ! ( $TableB.Contains($_) ))
    {
        $Unique2A.Add( $TableA[$_] )
    }
}

$Unique2A | Out-GridView



完全にテストされたわけではありませんが、サイズが一致するファイルのハッシュのみを計算するという点で役立つと思います。

$DirA     = 'c:\whatever'
$DirB     = 'c:\whenever'

$TestA = [Regex]::Escape($DirA)

$MasterList = gci $DirA , $DirB -Filter *.txt -recurse | Group Length

$Unique2A_BySize = ( $MasterList | ? Count -eq 1 |
     ? { $_.Group[0].DirectoryName -match $TestA } ).Group.FullName

$Unique2A_ByHash = ( $MasterLIst | ? Count -gt 1 | %{
    $_.Group | Get-FileHash | Group Hash |
        ? Count -eq 1 |
           ? { $_.Group[0].Path -match $TestA }
} ).Group.Path

( $Unique2A = $Unique2A_BySize + $Unique2A_ByHash ) | Out-GridView

読みにくくなると、改善される可能性があります。

$DirA     = 'c:\whatever'
$DirB     = 'c:\whenever'

$TestA = [Regex]::Escape($DirA)

$Unique2A = ( ( $MasterList = gci $DirA , $DirB -Filter *.txt -recurse | Group Length ) |
    ? Count -eq 1 |
        ? { $_.Group[0].DirectoryName -match $TestA } ).Group.FullName +
( $MasterLIst | ? Count -gt 1 | %{
    $_.Group | Get-FileHash | Group Hash |
        ? Count -eq 1 |
           ? { $_.Group[0].Path -match $TestA }
} ).Group.Path

$Unique2A | Out-GridView

答え2

ディレクトリリストをExcelにコピーし、UNIQUE関数を使用します。

関連情報