
Was ist bei zwei Verzeichnissen (DirA und DirB) die effizienteste Methode, um eine Liste der Dateien zu finden, die in DirA, aber nicht in DirB vorhanden sind?
Ich habe versucht, dies mithilfe des jdupes.exe --printunique --recurse -O
Tools zu tun. Dies hat jedoch den Nebeneffekt, dass eine Datei, die die oben genannten Kriterien erfüllt, ausgeschlossen wird, wenn Duplikate der besagten Datei auf DirA vorhanden sind.
Die Dateien können in völlig unterschiedlichen Unterverzeichnissen von DirA und DirB liegen und unterschiedliche Namen haben. Der Inhalt der Datei ist also das einzige dauerhafte Merkmal.
Antwort1
Die Saiten kamen zurück vonPower Shell'SGet-FileHashkönnen als Schlüssel zu einemHash-tabelleum Inhalte dem vollqualifizierten Pfad zuzuordnen. Dieser Code erstellt für jeden Pfad eine Hashtabelle mit den folgenden Einschränkungen.
- Leere Dateien werden ignoriert, da der Inhalts-Hash aller leeren Dateien identisch ist. (Sie können auch eine Liste der in jedem Verzeichnis gefundenen leeren Dateien erstellen.)
- Wenn Duplikate gefunden werdeninnerhalbdas Verzeichnis, das wir indizieren, wird nur die erste gefundene Datei zur Tabelle hinzugefügt
$HashOut
. Die$Dups
Tabelle enthält die Liste aller Pfade mit identischem Inhalt.
Power Shell:
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
Noch nicht vollständig getestet, aber ich glaube, dass dies den Zweck erfüllt, den Hash nur für Dateien zu berechnen, die in der Größe übereinstimmen.
$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
Was durch das schwieriger zu lesende verbessert werden kann:
$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
Antwort2
Ich würde die Verzeichnislisten in Excel kopieren und die Funktion UNIQUE verwenden