Я пытаюсь найти различия в содержимом двух структур папок с помощью Windows Powershell. Я использовал следующий метод, чтобы убедиться, что имена файлов совпадают, но этот метод не сообщает мне, одинаково ли содержимое файлов:
$firstFolder = Get-ChildItem -Recurse folder1
$secondFolder = Get-ChildItem -Recurse folder2
Compare-Object -ReferenceObject $firstFolder -DifferenceObject $secondFolder
Техника, описанная в этот вопрос ServerFault работает для сравнения одного файла, но эти папки содержат сотни файлов разной глубины.
Решение не обязательно должно указывать мне, что конкретно в файлах отличается - просто они есть. Меня не интересуют различия в метаданных, таких как дата, которые, как я уже знаю, отличаются.
Если вы хотите обернуть сравнение в цикл, я бы применил следующий подход:
$folder1 = "C:\Users\jscott"
$folder2 = "C:\Users\public"
# Get all files under $folder1, filter out directories
$firstFolder = Get-ChildItem -Recurse $folder1 | Where-Object { -not $_.PsIsContainer }
$firstFolder | ForEach-Object {
# Check if the file, from $folder1, exists with the same path under $folder2
If ( Test-Path ( $_.FullName.Replace($folder1, $folder2) ) ) {
# Compare the contents of the two files...
If ( Compare-Object (Get-Content $_.FullName) (Get-Content $_.FullName.Replace($folder1, $folder2) ) ) {
# List the paths of the files containing diffs
$_.FullName
$_.FullName.Replace($folder1, $folder2)
}
}
}
Обратите внимание, что это игнорирует файлы, которые не существуют в обоих $folder1
и $folder2
.
Я взял ответ jscott и расширил его, чтобы вывести файлы, которые присутствуют в одном, но не в другом, для тех, кто интересуется этим типом функций. Обратите внимание, что он также показывает достигнутый прогресс, поскольку мне было трудно это увидеть, учитывая огромные папки с небольшими отличиями. Похоже, сценарий мне повесили. Вот код PowerShell для этого:
$folder1 = "C:\Folder1"
$folder2 = "C:\Folder2"
# Get all files under $folder1, filter out directories
$firstFolder = Get-ChildItem -Recurse $folder1 | Where-Object { -not $_.PsIsContainer }
$failedCount = 0
$i = 0
$totalCount = $firstFolder.Count
$firstFolder | ForEach-Object {
$i = $i + 1
Write-Progress -Activity "Searching Files" -status "Searching File $i of $totalCount" -percentComplete ($i / $firstFolder.Count * 100)
# Check if the file, from $folder1, exists with the same path under $folder2
If ( Test-Path ( $_.FullName.Replace($folder1, $folder2) ) ) {
# Compare the contents of the two files...
If ( Compare-Object (Get-Content $_.FullName) (Get-Content $_.FullName.Replace($folder1, $folder2) ) ) {
# List the paths of the files containing diffs
$fileSuffix = $_.FullName.TrimStart($folder1)
$failedCount = $failedCount + 1
Write-Host "$fileSuffix is on each server, but does not match"
}
}
else
{
$fileSuffix = $_.FullName.TrimStart($folder1)
$failedCount = $failedCount + 1
Write-Host "$fileSuffix is only in folder 1"
}
}
$secondFolder = Get-ChildItem -Recurse $folder2 | Where-Object { -not $_.PsIsContainer }
$i = 0
$totalCount = $secondFolder.Count
$secondFolder | ForEach-Object {
$i = $i + 1
Write-Progress -Activity "Searching for files only on second folder" -status "Searching File $i of $totalCount" -percentComplete ($i / $secondFolder.Count * 100)
# Check if the file, from $folder2, exists with the same path under $folder1
If (!(Test-Path($_.FullName.Replace($folder2, $folder1))))
{
$fileSuffix = $_.FullName.TrimStart($folder2)
$failedCount = $failedCount + 1
Write-Host "$fileSuffix is only in folder 2"
}
}
Вы просто оборачиваете цикл вокруг правильного ответа из связанного вопроса, который уже ответил на него, и проходите по дереву каталогов, сравнивая каждый файл с тем же именем.
/ Edit: Если это действительно ваш вопрос, он больше подходит для SO, где вы, кажется, являетесь постоянным участником. Вы задаете вопрос по программированию. Я понимаю, что вы делаете это для целей типа системного администратора, и в этом случае я бы посоветовал вам использовать специальный инструмент, такой как WinDiff.
Сделай это:
compare (Get-ChildItem D:\MyFolder\NewFolder) (Get-ChildItem \\RemoteServer\MyFolder\NewFolder)
И даже рекурсивно:
compare (Get-ChildItem -r D:\MyFolder\NewFolder) (Get-ChildItem -r \\RemoteServer\MyFolder\NewFolder)
и это даже сложно забыть :)