在 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 函数

相关内容