Como diferencio duas pastas no Windows Powershell?

11

Estou tentando encontrar diferenças no conteúdo de duas estruturas de pastas usando o Windows Powershell. Eu usei o método a seguir para garantir que os nomes dos arquivos sejam os mesmos, mas esse método não informa se o conteúdo dos arquivos é o mesmo:

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

A técnica descrita nesta pergunta ServerFault funciona para diferenciar um único arquivo, mas essas pastas contêm centenas de arquivos em diversas profundidades.

A solução não precisa necessariamente me dizer o que especificamente há nos arquivos - apenas eles são. Não estou interessado em diferenças de metadados, como data, que eu já sei serem diferentes.

David Smith
fonte

Respostas:

15

Se você deseja agrupar a comparação em um loop, adotaria a seguinte abordagem:

$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)

        }
    }   
}

Observe que isso ignorará os arquivos que não existem nos dois $folder1 e $folder2.

jscott
fonte
5

Peguei a resposta de jscott e a expandi para gerar os arquivos presentes em um, mas não no outro, para aqueles que têm interesse nesse tipo de funcionalidade. Observe que também mostra o progresso feito, pois era difícil ver isso, considerando as enormes pastas com poucas diferenças. Parecia que o script estava pendurado para mim. Aqui está o código do PowerShell para isso:

$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
fonte
Por que você extrairia o conteúdo real de um arquivo ao chamar Compare-Object? É o que o Compare-Object faz. technet.microsoft.com/en-us/library/…
Casper Leon Nielsen
1

Você apenas quebra a resposta correta da sua pergunta vinculada que já respondeu a essa pergunta e percorre a árvore de diretórios comparando todos os arquivos com o mesmo nome.

/ Editar: se essa é realmente a sua pergunta, é mais apropriado para o SO, onde você parece ser um colaborador regular. Você está fazendo uma pergunta de programação. Entendo que você está fazendo isso para um propósito do tipo sysadmin; nesse caso, eu diria para você usar uma ferramenta criada especificamente para fins como o WinDiff.

mfinni
fonte
2
OK, este site não é apropriado para perguntas do tipo "Dê-me o codez". Se você precisar aprender a fazer loops no Powershell, compre um livro ou encontre tutoriais on-line; Há muitos.
mfinni
2
Eu acho que você acordou do lado errado da cama. Eu não sou um usuário comum do Powershell. Na minha pergunta, demonstrei uma técnica que estou tentando no momento e um link para uma pergunta que contém informações úteis adicionais para o meu problema. Não sei como combinar as duas técnicas, que é o meu problema e a razão pela qual fiz essa pergunta. Também é uma pergunta que não consegui responder usando as pesquisas do Google. Se você não for útil, considere excluir sua resposta.
19413 David Smith
2
@BigDave Literalmente, o primeiro resultado para PowerShell loop through filesno Google . vamos agora - um pouco de esforço de sua parte?
precisa saber é o seguinte
2
@ voretaq7 Acho que vocês me entendem mal como um usuário do PowerShell. Eu fiz essa pesquisa no google, tentei essa técnica e não obtive sucesso. Tentei explicar onde estou na pergunta acima. A pergunta à qual você vincula funciona em um único conjunto de arquivos. Eu tenho dois conjuntos que preciso comparar, nome a nome. Eu realmente não estou tentando ser preguiçoso aqui. Eu sei fazer um loop e sei como comparar. Como faço um loop e comparo dois conjuntos?
David Smith
1
Eu acho que fazer isso com o PS é um ótimo projeto. No entanto, o WinMerge (pensei que fosse o WinDiff, parvo) é realmente uma ótima ferramenta se você fizer isso com muita frequência. É literalmente construído para o trabalho. Experimente, o download é gratuito. Ele possui decompositores para a maioria dos tipos de arquivos e faz um ótimo trabalho de destaque, incluindo opções de como você deseja lidar com espaços em branco.
mfinni
0

Faça isso:

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

E mesmo recursivamente:

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

e é até difícil de esquecer :)

Francesco Mantovani
fonte