Como eu faço um diff do N-way?

14

Como difiro a saída de vários comandos? vimdiff pode suportar até quatro arquivos, mas diff parece suportar exatamente dois arquivos.

É diretamente possível com alguma variante de diff , ou eu tenho que salvar a saída de todos os comandos para arquivos temporários, escolher um e diferenciar o resto com ele?

Contexto:

Eu tenho que verificar a saída de um determinado comando em vários servidores e ver se todos eles concordam. No momento, apenas reportar se alguma diferença for encontrada parece bom, mas se possível, eu gostaria de poder dizer: X% servidores concordam um com o outro, Y% um com o outro; ou esse servidor Z é o ímpar.

Eu tenho uma configuração de LDAP multi-mestre de quatro vias e quero verificar se os valores de ContextCSN para todos os quatro estão de acordo uns com os outros.

Agora eu faço:

#! /bin/bash

for i in {1..4}.ldap 
do 
    ldapsearch -x -LLL -H ldap://$i -s base -b dc=example,dc=com contextCSN > $i.csn; 
done
set -e 
for i in {2..4}
do
    diff -q 1.csn $i.csn
done

E verifique o código de erro do script. Existem ferramentas melhores para isso?

Qualquer ferramenta que possa ser usada no Ubuntu 14.04 é bem-vinda.

    
por muru 24.12.2014 / 14:56

3 respostas

11

A ferramenta para fazer isso é Difusa . Também é geralmente disponível a partir de repos (pelo menos no Debian e no Arch, onde eu verifiquei). Funciona como você esperaria:

  diffuse file1 file2 file3 file4

e assim por diante.

    
por 24.12.2014 / 15:14
6

A ferramenta fdupes pode ser de alguma utilidade para você aqui (deve estar nos repositórios). Se você tiver um grande número de arquivos para comparar, poderá usá-lo para reduzir o trabalho necessário, identificando quais já são idênticos. Conforme observado abaixo, ele só funciona com argumentos de diretório. Se você tem todos os arquivos para diferenciar em um diretório, você pode fazer algo como:

fdupes .

Para identificar os arquivos que são os mesmos. Ou:

comm -13 <(fdupes . |sort -u) <(find . -maxdepth 1 | sort)

Para identificar arquivos únicos.

O comando diff3 também pode ser útil.

    
por 24.12.2014 / 15:30
5

Se você quiser apenas ver se os arquivos estão de acordo, você não precisa realmente de diff. Apenas use sha1sum ou algo parecido.

por exemplo:

#!/bin/sh
command="foo;bar|baz"
for server in server1 server2 server3 server4 server5 server6: do
    echo $server $(ssh $server "$command" |sha1sum)
done | sort -k2 

Isso lhe dará uma lista separada por espaços de servidores, pares sha1sum. Servidores com o mesmo sha1sum têm a mesma saída:

server1 55ca6286e3e4f4fba5d0448333fa99fc5a404a73 *-
server3 55ca6286e3e4f4fba5d0448333fa99fc5a404a73 *-
server6 55ca6286e3e4f4fba5d0448333fa99fc5a404a73 *-
server2 d961c3de6d6c99429806ae3d6d03f316a1168ac6 *-
server4 d961c3de6d6c99429806ae3d6d03f316a1168ac6 *-
server5 dcdc24e139db869eb059c9355c89c382de15b987 *-

Você pode fazer mais processamento para obter uma lista de servidores correspondentes, por exemplo:

#!/bin/sh
command="foo;bar|baz"
for server in server1 server2 server3 server4 server5: do
    echo $server $(ssh $server "$command" |sha1sum)
done | sort -k2 | while read srv sum; do
    if [ "$prevsum" == "$sum" ]; then 
        echo -n " "
    else
        echo
    fi
    echo -n $srv
    prevsum=$sum
done

que fornece resultados como:

server1 server3 server6
server2 server4
server5
    
por 24.12.2014 / 20:56