Diferença de espaço em branco entre dois arquivos no Linux


15

Eu tenho dois arquivos que, quando comparados com o diff, mostram que todas as linhas foram alteradas. Quando os comparo com diff -w(ignorando espaço em branco), ele mostra as poucas mudanças mínimas que eu espero.

Obviamente, há alguma diferença entre os espaços em branco em cada arquivo, mas não sei o que são ou como encontrá-los. Tentei editar os arquivos para garantir que o espaço em branco seja realmente caracteres de espaço (em oposição a guias), mas não tenho certeza do que mais fazer.

Eu usei o vim com :set list onpara confirmar que não havia espaço à direita no final das linhas.

Eu também acredito que cada arquivo possui terminadores de linha Linux, pois o vim não mostrava ^Mo final das linhas.


1
Você verificou o espaço em branco à direita (no final de uma linha)? Esse espaço será detectado por diffmas muitos editores, por padrão, não tornam esse espaço visível.
precisa saber é o seguinte

Boa sugestão. Eu usei o vim com ": set list on", que mostrava o "$" no final da linha e não havia espaço à direita. Vou atualizar minha pergunta
Romski

Se você é um vimusuário, já tentou usar vimdiff file1 file2para ver quais são as diferenças?
precisa saber é o seguinte

@ John1024 Eu não tinha conhecimento do vimdiff, mas parece promissor. Adicione-o como resposta e eu aceito
Romski 4/15/15

1
O Vim mostra ^ M somente quando detecta incorretamente uma finalização de linha Unix, mas o arquivo realmente possui final de linha DOS. Normalmente, isso acontece se você tiver final de linha mista em um único arquivo, por exemplo, aplicar um patch com final de linha diferente do arquivo original. Quando o vim detecta a linha do DOS terminando corretamente, ele não mostraria o ^ M.
Lie Ryan

Respostas:


7

Para os vimusuários, existe um utilitário útil para mostrar as diferenças exatas entre os arquivos:

vimdiff file1 file2

Isso colocará cada arquivo nas janelas, lado a lado, e as diferenças serão destacadas em cores.

Alguns comandos úteis quando em vimdiff

Enquanto estiver dentro vimdiff, alguns comandos úteis são:

  • ]c: pula para a próxima alteração

  • [c: pula para a alteração anterior

  • ctrl-W ctrl-W: mudar para outra janela

  • zo: dobras abertas

  • zc: fechar dobras

Exemplo

Aqui está um exemplo de vimdiffuma xtermcomparação entre duas versões de um cupsarquivo de configuração:

insira a descrição da imagem aqui

Você pode ver que seções longas de linhas idênticas foram recolhidas. Eles podem ser abertos novamente com zo.

O esquema de cores varia de acordo com as configurações da sua opção. No exemplo acima, quando uma linha aparece em um arquivo, mas não no outro, essa linha recebe um fundo azul escuro. No outro arquivo, as linhas ausentes são indicadas por linhas tracejadas. Quando uma linha aparece nos dois arquivos, mas possui algumas diferenças, as partes inalteradas têm um fundo rosa e as partes alteradas têm um fundo vermelho.


14

No FreeBSD ou na maioria dos sistemas Linux, você pode canalizar a saída do diff cat -v -e -tpara mostrar diferenças de espaço em branco.

diff file1 file2 | cat -vet

As guias serão mostradas como ^I, a $será mostrada no final de cada linha, para que você possa ver espaços em branco à direita, e os caracteres não imprimíveis serão exibidos como ^Xou M-X.

Se você possui GNU coreutils (disponível na maioria das distribuições Linux não-busybox), isso pode ser simplificado para

diff file1 file2 | cat -A

Em sistemas de ocupado, use catv -vet.


2

Um dos arquivos foi editado em uma máquina Windows?

O término de linha padrão no Windows é CRLF, onde no Linux é simplesmente LF (e nos Macs costumava ser CR, mas suspeito que isso tenha mudado desde o OS X).

Experimente wc -los arquivos e veja quantas linhas e veja se a diferença de tamanho é igual ao número de linhas (a última linha pode não ser finalizada em um arquivo).


Obrigado pela resposta rápida. Fazer uma contagem de linhas mostra que um arquivo tem mais 5 linhas (espero que tenha feito edições). Eu obtive um arquivo de uma máquina Linux e o outro foi retirado de um repositório de código no Linux. Acredito que visualizar um arquivo com terminadores do Windows no vim mostrará o último caractere como ^ M e não é esse o caso.
Romski 04/02

3
O vim é realmente inteligente o suficiente para detectar automaticamente o término da linha, consulte stackoverflow.com/questions/3852868 para obter detalhes.
fencepost

Eu não estava ciente disso! Vou verificar
novamente

2

odpode ajudar. O comando Octal Dump pode mostrar o conteúdo em hexadecimal. Isso pode ajudá-lo a ver quais bytes, incluindo bytes nulos ou espaço em branco inesperado, estão em um arquivo. As possíveis causas comuns podem ser LF vs CRLF, guias vs espaços ou ASCII vs Unicode (que geralmente podem ter apenas um byte nulo antes de cada byte normalmente visível). od -x filenamedeve revelar qualquer um desses padrões. Se você deseja uma maneira mais elaborada de visualizar o arquivo, qualquer "editor hexadecimal" pode ser bom. O legal odé que, como o cutcomando, ele está embutido em muitos sistemas Unix. Portanto, muitas vezes, nenhuma instalação separada é necessária.

Se você precisar que os arquivos sejam mais parecidos, trfaça algumas alterações e sedfaça mais. Eu provavelmente começaria ls -la ver qual arquivo é maior, depois visualizaria os bytes para ver o que precisa ser alterado e depois alteraria um dos arquivos para que parecessem mais semelhantes.


1

Para descobrir onde estão os espaços em branco e as guias reais, você pode substituí-los usando, sedpor exemplo:

$ cat file
  line 1
  line 2
    line 6
        line 7
$ sed 's/ /-/g; s/\t/<tab>/g' file
--line-1
--line-2
<tab>line-6
<tab><tab>line-7

E agora compare os dois arquivos.


Melhor ainda, você pode executar esse filtro na saída diff. Ou você pode usar o filtro pronto cat, como em superuser.com/a/913368/37154
clacke

0

O conteúdo a seguir foi copiado aqui da seção "pergunta" acima, escrita por Romski.

Ambos vimdiffe diff file1 file2 | cat -Aforam muito úteis do ponto de vista das ferramentas.

Por fim, encontrei mais um problema. Alguns dos meus arquivos foram codificados com UTF-8 BOM. Isso foi destacado usando diff file1 file2 | cat -A. Isso se manifestou como M-oM-;M-?no início do arquivo afetado:

$ diff file1 file2 | cat -A
< package com.mycompany;$
---$
> M-oM-;M-?package com.mycompany;$

Embora tenha havido vários problemas, listei alguns comandos abaixo para aqueles que precisam limpar seus arquivos:

# recursively remove UTF8 BOM
find . -type f -exec sed -i -e '1s/^\xEF\xBB\xBF//' {} \;

# recursively replace CRLF with LF
find . -type f -print0 | xargs -0 dos2unix
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.