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:
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.
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 $folder2If(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.
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 +1Write-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 $folder2If(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 +1Write-Host"$fileSuffix is on each server, but does not match"}}
else
{
$fileSuffix = $_.FullName.TrimStart($folder1)
$failedCount = $failedCount +1Write-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 +1Write-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 $folder1If(!(Test-Path($_.FullName.Replace($folder2, $folder1)))){
$fileSuffix = $_.FullName.TrimStart($folder2)
$failedCount = $failedCount +1Write-Host"$fileSuffix is only in folder 2"}}
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.
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.
@ 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.
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.
fonte
PowerShell loop through files
no Google . vamos agora - um pouco de esforço de sua parte?Faça isso:
E mesmo recursivamente:
e é até difícil de esquecer :)
fonte