No bash, como eu comparo duas pastas para garantir que elas contenham os mesmos conjuntos de arquivos?

2

Eu copiei uma pasta massiva de uma máquina Windows para uma máquina Linux e, como alguns nomes de arquivos são muito grandes (e alguns outros erros que eu ignorei), alguns arquivos não puderam ser copiados. Atualmente estou executando diff -r entre as duas pastas para gerar uma lista dos arquivos que estão na pasta original, mas não na cópia. No entanto, até agora, as únicas coisas que parece ter reconhecido são pastas ausentes, ou seja, parece estar ignorando arquivos. Existe uma maneira melhor de fazer essa comparação? Em particular, estou preocupado que o Bash simplesmente não consiga reconhecer esses arquivos com nomes de arquivos muito longos.

    
por J. Min 23.01.2018 / 23:42

4 respostas

1

Você pode fazer algo não totalmente diferente:

(cd some/where; ls -lR) > somewhere.txt
(cd else/where; ls -lR) > elsewhere.txt
diff somewhere.txt elsewhere.txt

Eu não tentei isso, isso depende dos metadados do arquivo (datas etc) serem preservados ( cp -p ... ) e dos nomes de arquivos de classificação ls na mesma ordem (que deveria).

    
por 24.01.2018 / 00:02
1

diff --recursive ( -r ) captura alterações de arquivos, mesmo em subdiretórios.

Você pode preferir usar diff --unified --recursive , no entanto. Ele cria um diff unificado , que exibe as linhas alteradas prefixadas com (+) para additon e (-) para remoção. Convenientemente, também exibe linhas circunvizinhas (ou seja, contexto ), para que você possa descobrir o que está acontecendo lá.

    
por 24.01.2018 / 00:35
1

Se o rsync for uma opção viável, talvez as opções --itemize-changes (-i) e --dry-run sejam úteis:

rsync -zaic src_dir/ dest_dir/ --dry-run

-z comprime arquivos durante a transferência, -a copia no modo de arquivo e -c baseia as comparações de arquivos em somas de controle em vez de data de modificação ou tamanho.

-i listará os arquivos individuais que são diferentes e --dry-run significa que nenhum dado será transferido, apenas gerando uma lista.

    
por 24.01.2018 / 00:25
1
diff <(cd /first/path/ && find ./ | sort) <(cd /second/path/ && find ./ | sort)

Isso é semelhante a esta outra resposta , mas:

  • Estou usando find para gerar listas de objetos (arquivos, diretórios); cabe aqui melhor que ls porque sua saída contém apenas caminhos.
  • sort garante que a ordem relativa dos objetos seja preservada, independentemente de em que ordem cada find os relacione.
  • A sintaxe <(…) evita arquivos temporários em bash .
  • find será executado somente se o cd correspondente for bem-sucedido, graças ao operador && . Isso evitará que você execute find no diretório atual se houver um erro de digitação em qualquer caminho.

Notas adicionais:

  • Os caminhos retornados por find serão relativos aos diretórios em que cd . Certifique-se de que /first/path/ e /second/path/ correspondam entre si.
  • A saída vazia de diff indica que os dois diretórios são idênticos; mas lembre-se…
  • … o comando opera somente em caminhos, não verifica se o conteúdo ou metadados correspondem.
  • Nomes de objeto com caracteres incomuns (por exemplo, com novas linhas) irão quebrar a lógica.
por 25.01.2018 / 01:01