Ignora os finais de linha ao usar o Rsync

3

Eu quero sincronizar dois diretórios. O primeiro tem CRLF e terminações de linha normais, o segundo diretório também possui arquivos com CRLF e terminações normais de linha.

O problema é, quando eu executo este código:

  rsync -azr --exclude=images --dry-run --delete --checksum --out-format="/%f" /dir1 /dir2

Ele mostra que muitos arquivos idênticos, mas com codificação diferente, serão sincronizados e eu só quero sincronizar os diferentes arquivos de conteúdo.

Com diff , é possível fazer isso:

diff --strip-trailing-cr file1 file2

Mas não consegui encontrar nada parecido com isso para o Rsync. Como posso sincronizar apenas os arquivos com conteúdo diferente?

    
por Sergio 14.09.2018 / 10:20

1 resposta

3

Não há opção para ignorar finais de linha para rsync

Como você descobriu, rsync considera os arquivos com diferentes términos de linha ser diferente. Isso é inconveniente na sua situação porque os arquivos são visualmente / semanticamente iguais.

rsync decide o que sincronizar em um arquivo com base nas somas de verificação dos blocos. Há uma boa visão geral sobre isso :

(T)he old version of the file is split into blocks of, e.g. 1024 or 2048 bytes, and a checksum is calculated for each block.

The new file is then searched byte for byte for blocks with checksums matching those in the old version. Here is a diagram illustrating this process:

diffing 1

Repeating these operations on the new version of the file you will iterate through the file byte for byte. During this iteration you will find two types of data in the file:

  • Blocks of data that matches blocks in the old file.
  • Sequences of bytes that is not part of a matching block.

De RSync - Detectando diferenças de arquivos por Jakob Jenkov .

Se você estiver interessado, a próxima seção está nas somas de verificação usadas . No entanto, o ponto principal da soma de verificação é que ela funciona em bytes e seus arquivos têm bytes diferentes por causa dos términos de linha . Como tal, rsync está detectando corretamente que eles são diferentes e, portanto, estão transferindo-os.

Evite transferir arquivos com diferentes terminações de linha, sanitizando a pré-transferência

A melhor maneira de fazer isso é garantir que todos os seus arquivos tenham finais de linha consistentes, ou higienizar eles, como Kamil sugerido nos comentários.

Como você faz isso é com você. Você pode decidir que fará a alteração quando os arquivos forem gerados, editados ou atualizados. Ou você pode fazer isso como uma etapa de pré-transferência.

Aplique a higienização apenas aos arquivos necessários

Se você se higienizar, certifique-se de não aplicá-lo cegamente , como Kamil ainda avisa:

One shouldn't use any conversion tool blindly on all files. Even if the tool tries to guess if a file is text or binary, it's only heuristics. CRLF may appear inside a binary file; blocks that look like text may appear as well. Modifying a binary file by removing some bytes will most probably corrupt it.

(ênfase minha)

Por exemplo, se você tiver arquivos nos dois diretórios que você sabe que são arquivos de texto que precisam ser higienizados, aplique a etapa de sanitização somente a esse subconjunto.

Qual ferramenta devo usar para alterar os finais?

Uma solução completa está além do escopo desta resposta. Existem várias sugestões sobre este SO QA , incluindo dos2unix , tr , sed , awk , perl .

Por exemplo:

You can use tr to convert from DOS to Unix; however, you can only do this safely if CR appears in your file only as the first byte of a CRLF byte pair. This is usually the case. You then use:

tr -d '5' <DOS-file >UNIX-file

However, if you're going to have to do this very often (more than once, roughly speaking), it is far more sensible to install the conversion programs (e.g. dos2unix and unix2dos, or perhaps dtou and utod) and use them.

de resposta de Jonathan Leffler .

Tenha em mente o aviso acima ao usar qualquer uma dessas ferramentas, no entanto.

    
por 14.09.2018 / 13:03