Como canalizar saída de find como entrada para diff?

3

Esta é uma questão básica sobre o bash, mas não consegui encontrar uma solução.

Eu tenho muitos subdiretórios com arquivos com nomes idênticos e quero comparar todos eles por identidade.

Eu posso retornar a lista desses arquivos com

find . -name "protein.mol2"

Eu sei que o arquivo pode ser usado como consulta em diff

diff -q --from-file dir1/file dir2/file dir3/file; echo $?

Como canalizar a saída de find para diff ?

    
por DrDom 16.10.2015 / 10:54

3 respostas

7

A opção --from-file permite comparar um arquivo com vários arquivos (em vez de algo como tar --files-from , que lê uma lista de arquivos para operar a partir de um arquivo). Ele tem um --to-file análogo, que dos dois que você usa dependeria da "direção" relativa da mudança. Como você está usando -q , que diz apenas que, se houver uma diferença, esperamos que isso não seja importante para você aqui.

Suponho que você tenha um arquivo de referência e deseja compará-lo a um conjunto de arquivos com nomes idênticos, portanto, qualquer um deles deve funcionar:

diff -q --from-file dir1/protein.mol2 $(find . -name protein.mol2)
find . -name protein.mol2 | xargs diff -q --from-file dir1/protein.mol2

No primeiro caso, diff será executado apenas uma vez e seu código de saída refletirá se foram encontradas ou não diferenças no conjunto.

No segundo caso, diff pode ser executado mais de uma vez. Este segundo formulário pode ser usado no caso de você ter um grande número de arquivos (ou nomes muito longos de arquivos / diretórios) e atingir um limite de argumento de comando (geralmente 128kB em sistemas Linux).

    
por 16.10.2015 / 11:47
2

tente

diff -q --from-file $(find . -name "protein.mol2" -print) ; echo $?
  • $( ) construct basicamente insere uma lista de arquivos do find.
por 16.10.2015 / 11:05
0

Se você quiser compará-los apenas com identidade, poderá usar algo como uma soma de verificação para marcar o arquivo com base em seu conteúdo:

find . -name 'protein.mol2' -exec cksum {} + | sort

Você pode salvar a saída em um arquivo. Linhas com o primeiro par de números iguais representam arquivos que são (quase certamente) idênticos. Esta extensão para o comando irá agrupar arquivos por identidade:

find . -name 'protein.mol2' -exec cksum {} + |
sort |
while read c1 c2 file
do
    test "$c1-$c2" != "$o1-$o2" && echo
    echo "$file"
    o1="$c1" o2="$c2"
done

Como um one-liner é find . -name 'protein.mol2' -exec cksum {} + | sort | while read c1 c2 file; do test "$c1-$c2" != "$o1-$o2" && echo; echo "$file"; o1="$c1" o2="$c2"; done mas provavelmente seria melhor colocá-lo em um arquivo de script para reutilização.
por 16.10.2015 / 14:55

Tags