Eu tenho dois arquivos de texto e quero encontrar as diferenças entre eles usando o Windows Powershell. Existe algo semelhante à ferramenta diff Unix disponível? Ou existe outra maneira de não considerar?
Eu tentei comparar objeto, mas obtenha esta saída enigmática:
PS C:\> compare-object one.txt two.txt
InputObject SideIndicator
----------- -------------
two.txt =>
one.txt <=
windows
powershell
Brian Willis
fonte
fonte
-SyncWindow 0
corrigir isso, acredito, embora não tenha certeza se foi introduzido apenas recentemente. Não é particularmente inteligente sobre isso, no entanto.Uma maneira mais simples de fazer isso é escrever:
fonte
diff
, como outras respostas aqui observadas. E quando usei uma expressão mais complexa no lugar decat
obtive uma saída incorreta, por isso, juntarei as outras pessoas na recomendação para evitar isso no PowerShell se você vier do * nix.Ou você pode usar o
fc
comando DOS da seguinte forma (isso mostra a saída de ambos os arquivos para que você precise verificar as diferenças):fc
é um alias para o cmdlet Format-Custom, certifique-se de inserir o comando comofc.exe
. Observe que muitos utilitários do DOS não lidam com a codificação UTF-8.Você também pode gerar um processo CMD e executá
fc
-lo.Isso instrui o PowerShell a iniciar um processo com o programa 'cmd' usando os parâmetros entre aspas. Nas aspas, é a opção '/ c' cmd para executar o comando e finalizar. O comando real a ser executado pelo cmd no processo está
fc filea.txt fileb.txt
redirecionando a saída para o arquivodiff.txt
.Você pode usar o DOS
fc.exe
de dentro do PowerShell.fonte
O diff on * nix não faz parte do shell, mas um aplicativo separado.
Existe algum motivo para você não poder usar o diff.exe no PowerShell?
Você pode baixar uma versão do pacote UnxUtils ( http://unxutils.sourceforge.net/ )
fonte
git diff
, porque já o tinha instalado. Nemfc.exe
nemCompare-Object
produziu a saída que eu esperava.O compare-object (também conhecido como diff) é patético se você espera que se comporte como um diff unix. Eu tentei o diff (gc file1) (gc file2) e, se uma linha é muito longa, não consigo ver o diff real e, mais importante, não sei dizer em qual número de linha o diff está.
Quando tento adicionar -passthru, agora vejo a diferença, mas perco em qual arquivo está a diferença e ainda não recebo o número da linha.
Meu conselho, não use o PowerShell para encontrar diferenças nos arquivos. Como outra pessoa notou, o fc funciona e funciona um pouco melhor do que o objeto comparar, e ainda melhor é baixar e usar ferramentas reais, como o emulador unix que o Mikeage mencionou.
fonte
-SyncWindow
é maxint por padrão. Definir isso como 0 também não funcionadiff
... E quando eu passei um pipe(... | select-object ...)
como entrada, ele imprimiu bobagens, então desisti.Como outros observaram, se você estava esperando uma saída diff unix-y, o uso do apelido diff do powershell o deixaria muito decepcionado. Por um lado, você tem que segurar a mão para realmente ler arquivos (com gc / get-content). Por outro lado, o indicador de diferença está à direita, longe do conteúdo - é um pesadelo de legibilidade.
A solução para quem procura uma saída sã é
adicione a linha
O argumento -force é necessário porque o Powershell é bastante precioso sobre esse alias embutido específico. Se alguém estiver interessado, com o GnuWin32 instalado, também incluo o seguinte no meu perfil do PowerShell:
Principalmente porque o Powershell não entende os argumentos que são executados juntos e digitando, por exemplo "rm -Force -Recurse" é muito mais esforço do que "rm -rf".
O Powershell possui alguns recursos interessantes, mas há algumas coisas que ele simplesmente não deve tentar fazer por mim.
fonte
O WinMerge é outra boa ferramenta diff baseada em GUI.
fonte
Há também o Windiff, que fornece uma interface de interface gráfica do usuário (ótima para uso com programas CVS / SVN baseados em GUI)
fonte
fc.exe
é melhor para comparação de texto, pois ele foi projetado para funcionar como * nix diff, ou seja, compara linhas sequencialmente, mostrando as diferenças reais e tentando sincronizar novamente (se as seções diferentes tiverem comprimentos diferentes). Ele também possui algumas opções de controle úteis (texto / binário, distinção entre maiúsculas e minúsculas, números de linhas, comprimento de ressincronização, tamanho do buffer incompatível) e fornece status de saída (-1 sintaxe incorreta, 0 arquivos iguais, 1 arquivo diferente, 1 arquivo diferente e 2 arquivos ausentes). Sendo um utilitário (muito) antigo do DOS, ele tem algumas limitações. Mais notavelmente, ele não funciona automaticamente com Unicode, tratando os 0 MSB de caracteres ASCII como um terminador de linha, para que o arquivo se torne uma sequência de 1 linha de caracteres (@kennycoc: use a opção / U para especificar AMBOS os arquivos são Unicode, WinXP em diante ) e também possui um tamanho de buffer de linha direta de 128 caracteres (128 bytes ASCII,compare-object foi desenvolvido para determinar se 2 objetos são idênticos em termos de membros. se os objetos são coleções, eles são tratados como SETS (consulte a ajuda de comparação de objetos), ou seja, coleções não ordenadas sem duplicatas. 2 conjuntos são iguais se tiverem os mesmos itens de membro, independentemente de pedido ou duplicação. Isso limita severamente sua utilidade na comparação de arquivos de texto quanto a diferenças. Primeiramente, o comportamento padrão coleta as diferenças até que todo o objeto (file = array of strings) tenha sido verificado, perdendo as informações sobre a posição das diferenças e obscurecendo quais diferenças estão emparelhadas (e não existe um conceito de número de linha para um SET de cordas). O uso de -synchwindow 0 fará com que as diferenças sejam emitidas à medida que ocorrem, mas impede a tentativa de sincronizar novamente. Se um arquivo tiver uma linha extra, as comparações de linha subsequentes poderão falhar, mesmo que os arquivos sejam idênticos (até que exista uma compensação linha extra no outro arquivo realinhando as linhas correspondentes). No entanto, o PowerShell é extremamente versátil e uma comparação útil de arquivos pode ser feita utilizando essa funcionalidade, embora ao custo de uma complexidade substancial e com algumas restrições sobre o conteúdo dos arquivos. Se você precisar comparar arquivos de texto com linhas longas (> 127 caracteres) e onde as linhas correspondem principalmente a 1:
onde xx é o comprimento da linha mais longa + 9
Explicação
(gc file | % -begin { $ln=0 } -process { '{0,6}<<:{1}' -f ++$ln,$_ })
obtém o conteúdo do arquivo e anexa o número da linha e o indicador do arquivo (<< ou >>) a cada linha (usando o operador de cadeia de formatação) antes de passá-lo para diff.-property { $_.substring(9) }
diz ao diff para comparar cada par de objetos (strings) ignorando os 9 primeiros caracteres (que são o número da linha e o indicador de arquivo). Isso utiliza a capacidade de especificar uma propriedade calculada (o valor de um bloco de script) em vez do nome de uma propriedade.-passthru
faz com que diff produza os diferentes objetos de entrada (que incluem o número da linha e o indicador de arquivo) em vez dos diferentes objetos comparados (que não).sort-object
depois coloca todas as linhas de volta em seqüência.out-string interrompe o truncamento padrão da saída para caber na largura da tela (conforme observado por Marc Towersap) especificando uma largura grande o suficiente para evitar o truncamento. Normalmente, essa saída é colocada em um arquivo que é visualizado usando um editor de rolagem (por exemplo, o bloco de notas).
Nota
O formato do número da linha {0,6} fornece um número de linha com 6 caracteres, justificado à direita e preenchido com espaço (para classificação). Se os arquivos tiverem mais de 999.999 linhas, basta alterar o formato para ser maior. Isso também requer a alteração do
$_.substring
parâmetro (3 a mais que a largura do número da linha) e o valor xx da cadeia de caracteres (comprimento máximo da linha +$_.substring
parâmetro).fonte