Как различить две папки в Windows Powershell?

11

Я пытаюсь найти различия в содержании двух структур папок с помощью Windows Powershell. Я использовал следующий метод, чтобы убедиться, что имена файлов совпадают, но этот метод не сообщает мне, совпадает ли содержимое файлов:

$firstFolder = Get-ChildItem -Recurse folder1
$secondFolder = Get-ChildItem -Recurse folder2
Compare-Object -ReferenceObject $firstFolder -DifferenceObject $secondFolder

Методика, описанная в этом вопросе о ServerFault, работает для разграничения одного файла, но эти папки содержат сотни файлов различной глубины.

Решение не обязательно должно сказать мне, что конкретно в файлах отличается - просто они есть. Меня не интересуют различия в метаданных, таких как дата, которые, как я уже знаю, отличаются.

Дэвид Смит
источник

Ответы:

15

Если вы хотите обернуть сравнение в цикл, я бы выбрал следующий подход:

$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
источник
5

Я взял ответ Джскота расширенным, чтобы вывести файлы, которые присутствуют в одном, но не в другом, для тех, кто заинтересован в таком типе функциональности. Пожалуйста, обратите внимание, что это также показывает достигнутый прогресс, так как мне было трудно увидеть это, учитывая огромные папки с не очень большим количеством различий. Похоже, сценарий был повешен для меня. Вот код 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"
    }
}
helios456
источник
Зачем вам извлекать фактическое содержимое файла при вызове Compare-Object? Вот что делает Compare-Object. technet.microsoft.com/en-us/library/…
Каспер Леон Нильсен
1

Вы просто оборачиваете цикл вокруг правильного ответа из вашего связанного вопроса, который уже ответил на этот вопрос, и обходите дерево каталогов, сравнивая каждый файл с тем же именем.

/ Edit: если это на самом деле ваш вопрос, он больше подходит для SO, где вы, кажется, постоянный участник. Вы задаете вопрос программирования. Я понимаю, что вы делаете это для целей типа sysadmin, и в этом случае я бы сказал вам использовать специальный инструмент, такой как WinDiff.

mfinni
источник
2
ОК, этот сайт не подходит для вопросов типа «Дайте мне код». Если вам нужно начать изучение циклов в Powershell, купите книгу или найдите онлайн-учебники; много.
mfinni
2
Я думаю, ты проснулся не с той стороны кровати. Я не обычный пользователь Powershell. В своем вопросе я продемонстрировал и технику, которую я сейчас пробую, и ссылку на вопрос, который содержит дополнительную полезную информацию для моей проблемы. Я не знаю, как совместить эти две техники, что является моей проблемой и причиной, по которой я задал этот вопрос. Это также вопрос, на который я не смог ответить с помощью поиска Google. Если вы не собираетесь помогать, рассмотрите возможность удаления своего ответа.
Дэвид Смит
2
@BigDave Буквально первый результат для PowerShell loop through filesGoogle . давай сейчас - немного усилий с вашей стороны?
voretaq7
2
@ voretaq7 Я думаю, что вы, ребята, неправильно понимаете меня как пользователя PowerShell. Я сделал этот поиск в Google, попробовал эту технику, и не удалось. Я попытался объяснить, где я нахожусь в вопросе выше. Вопрос, на который вы ссылаетесь, работает с одним набором файлов. У меня есть два набора, которые мне нужно сравнить, имя-имя. Я действительно не пытаюсь быть ленивым здесь. Я знаю, как сделать цикл, и я знаю, как сравнить. Как сделать цикл и сравнить два набора?
Дэвид Смит
1
Я думаю, что делать это с PS - отличный маленький проект. Тем не менее, WinMerge (думал, что это WinDiff, глупый я) действительно отличный инструмент, если вы собираетесь делать это очень часто. Это буквально построено для работы. Попробуйте, загрузка бесплатна. У него есть декомпозеры для большинства типов файлов, и он отлично справляется с выделением, включая опции для обработки пробелов.
mfinni
0

Сделай это:

compare (Get-ChildItem D:\MyFolder\NewFolder) (Get-ChildItem \\RemoteServer\MyFolder\NewFolder)

И даже рекурсивно

compare (Get-ChildItem -r D:\MyFolder\NewFolder) (Get-ChildItem -r \\RemoteServer\MyFolder\NewFolder)

и даже трудно забыть :)

Франческо Мантовани
источник