fbpx

Comandos Linux – Comando diff

Comando diff do Linux

Atualizado: 05/04/2019 por Computer Hope

comando diff

Nos sistemas operacionais do tipo Unix, o comando diff analisa dois arquivos e imprime as linhas diferentes. Em essência, ele fornece um conjunto de instruções sobre como alterar um arquivo para torná-lo idêntico ao segundo arquivo.

Este documento cobre a versão GNU / Linux do diff .

Descrição

O software diff não altera os arquivos que ele compara. No entanto, opcionalmente, pode gerar um script (se a opção -e for especificada) para o programa ed ou ex que pode ser usado para aplicar as alterações.

Por exemplo, considere dois arquivos, file1.txt e file2.txt .

Se file1.txt contiver as quatro linhas de texto a seguir:

  Eu preciso comprar maçãs.
 Eu preciso lavar a roupa.
 Eu preciso lavar o cachorro.
 Eu preciso obter o carro detalhado.

… e file2.txt contém estas quatro linhas:

  Eu preciso comprar maçãs.
 Eu preciso lavar a roupa.
 Eu preciso lavar o carro.
 Eu preciso detalhar o cachorro.

… então podemos usar o diff para exibir automaticamente para nós quais linhas diferem entre os dois arquivos com este comando:

  diff file1.txt file2.txt

… e a saída será:

  2,4c2,4
 <Eu preciso lavar a roupa.
 <Eu preciso lavar o cachorro.
 <Preciso detalhar o carro.
 ---
 > Eu preciso lavar a roupa.
 > Preciso lavar o carro.
 > Preciso detalhar o cachorro.

Vamos dar uma olhada no que essa saída significa. O importante a lembrar é que, quando diff está descrevendo essas diferenças para você, está fazendo isso em um contexto prescritivo : está lhe dizendo como alterar o primeiro arquivo para que ele corresponda ao segundo arquivo.

A primeira linha da saída do diff conterá:

  • números de linhas correspondentes ao primeiro arquivo,
  • uma letra ( a para adicionar , c para alterar ou d para excluir ) e
  • números de linhas correspondentes ao segundo arquivo.

Em nossa saída acima, ” 2,4c2,4 ” significa: “As linhas 2 a 4 no primeiro arquivo precisam ser suspensas para corresponder às linhas 2 a 4 no segundo arquivo”. Em seguida, ele nos diz quais são essas linhas em cada arquivo:

  • Linhas precedidas por um < são linhas do primeiro arquivo;
  • linhas precedidas por > são linhas do segundo arquivo.

Os três hífens (”  “) apenas separam as linhas do arquivo 1 e do arquivo 2.

Vejamos outro exemplo. Digamos que nossos dois arquivos sejam assim:

file1.txt :

  Eu preciso ir para a loja.
  Eu preciso comprar algumas maçãs.
  Quando chegar em casa, lavarei o cachorro.

file2.txt :

  Eu preciso ir para a loja.
  Eu preciso comprar algumas maçãs.
  Ah, sim, eu também preciso comprar queijo ralado.
  Quando chegar em casa, lavarei o cachorro.
  diff file1.txt file2.txt

Resultado:

  2a3
 > Ah, sim, eu também preciso comprar queijo ralado.

Aqui, a saída está nos dizendo “Após a linha 2 no primeiro arquivo, uma linha precisa ser dded: linha 3 do segundo arquivo”. Em seguida, ele nos mostra o que é essa linha.

Agora vamos ver como fica quando diff nos diz que precisamos excluir uma linha.

file1 :

  Eu preciso ir para a loja.
 Eu preciso comprar algumas maçãs.
 Quando chegar em casa, lavarei o cachorro.
 Eu prometo.

arquivo2 :

  Eu preciso ir para a loja.
 Eu preciso comprar algumas maçãs.
 Quando chegar em casa, lavarei o cachorro.

Nosso comando:

  diff file1.txt file2.txt

A saída:

  4d3
 <Eu prometo.

Aqui, a saída está nos dizendo “Você precisa excluir a linha 4 no primeiro arquivo para que os dois sejam sincronizados na linha 3 “. Em seguida, ele mostra o conteúdo da linha que precisa ser excluída.

Visualizando Saída diff no Contexto

Os exemplos acima mostram a saída padrão do diff . Ele deve ser lido por um computador, não por um ser humano; portanto, para fins humanos, às vezes ajuda a ver o contexto das mudanças.

diff GNU , que é a versão que a maioria dos usuários do linux usará, oferece duas maneiras diferentes de fazer isso: “modo de contexto” e “modo unificado”.

Para visualizar diferenças no modo de contexto, use a opção -c . Por exemplo, digamos que file1.txt e file2.txt contêm o seguinte:

file1.txt :

  maçãs
 laranjas
 kiwis
 cenouras

file2.txt :

  maçãs
 kiwis
 cenouras
 toranjas

Vamos dar uma olhada na saída contextual do diff desses dois arquivos. Nosso comando é:

  diff -c arquivo1.txt arquivo2.txt

E nossa saída é assim:

  *** file1.txt 2014-08-21 17: 58: 29.764656635 -0400
 --- file2.txt 2014-08-21 17: 58: 50.768989841 -0400
 ***************
 *** 1,4 ****
   maçãs
 - laranjas
   kiwis
   cenouras
 --- 1,4 ----
   maçãs
   kiwis
   cenouras
 + toranjas

As duas primeiras linhas desta saída nos mostram informações sobre nosso arquivo “de” (arquivo 1) e nosso arquivo “para” (arquivo 2). Ele lista o nome do arquivo , a data da modificação e a hora da modificação de cada um de nossos arquivos, um por linha. O arquivo “de” é indicado por ” *** ” e o arquivo “para” é indicado por ”  “.

A linha ” *************** ” é apenas um separador.

A próxima linha possui três asteriscos (” *** “) seguidos por um intervalo de linhas do primeiro arquivo (nesse caso, as linhas 1 a 4 , separadas por vírgula). Depois, quatro asteriscos (” **** “).

Então ele nos mostra o conteúdo dessas linhas. Se a linha não for alterada, será prefixada por dois espaços. Se a linha for alterada, no entanto, será prefixada por um caractere indicativo e um espaço. Os significados dos caracteres são os seguintes:

personagemsignificado
!Indica que esta linha faz parte de um grupo de uma ou mais linhas que precisam ser alteradas. Há um grupo correspondente de linhas prefixadas com ” ! ” No contexto do outro arquivo também.
+Indica uma linha no segundo arquivo que precisa ser adicionada ao primeiro arquivo.
Indica uma linha no primeiro arquivo que precisa ser excluída.

Após as linhas do primeiro arquivo, há três traços (”  “), depois um intervalo de linhas e quatro traços (” —- “). Isso indica o intervalo de linhas no segundo arquivo que será sincronizado com as alterações no primeiro arquivo.

Se houver mais de uma seção que precise ser alterada, o diff mostrará essas seções uma após a outra. Linhas do primeiro arquivo ainda serão indicadas com ” *** ” e linhas do segundo arquivo com ”  “.

Modo unificado

O modo unificado (a opção -u ) é semelhante ao modo de contexto, mas não exibe nenhuma informação redundante. Aqui está um exemplo, usando os mesmos arquivos de entrada que nosso último exemplo:

file1.txt :

  maçãs
 laranjas
 kiwis
 cenouras

file2.txt :

  maçãs
 kiwis
 cenouras
 toranjas

Nosso comando:

  diff -u arquivo1.txt arquivo2.txt

A saída:

  --- file1.txt 2014-08-21 17: 58: 29.764656635 -0400
 +++ file2.txt 2014-08-21 17: 58: 50.768989841 -0400
 @@ -1,4 +1,4 @@
  maçãs
 laranjas
  kiwis
  cenouras
 + toranjas

A saída é semelhante à acima, mas como você pode ver, as diferenças são “unificadas” em um conjunto.

Localizando diferenças no conteúdo do diretório

diff também pode comparar diretórios fornecendo nomes de diretórios em vez de nomes de arquivos. Veja a seção Exemplos .

Usando diff para criar um script de edição

A opção -e diz ao diff para gerar um script, que pode ser usado pelos programas de edição ed ou ex , que contém uma sequência de comandos. Os comandos são uma combinação de c (alterar), a (adicionar) e d (excluir) que, quando executados pelo editor, modificam o conteúdo do arquivo1 (o primeiro arquivo especificado na linha de comando diff ) para que ele corresponda o conteúdo do arquivo2 (o segundo arquivo especificado).

Digamos que temos dois arquivos com o seguinte conteúdo:

file1.txt :

  Era uma vez uma garota chamada Perséfone.
 Ela tinha cabelos pretos.
 Ela amava a mãe mais do que tudo.
 Ela gostava de sentar ao sol com sua gata, Daisy.
 Ela sonhava em ser pintora quando cresceu.

file2.txt

  Era uma vez uma garota chamada Perséfone.
 Ela tinha cabelos ruivos.
 Ela adorava biscoitos de chocolate mais do que tudo.
 Ela gostava de sentar ao sol com sua gata, Daisy.
 Ela olhava para as nuvens e sonhava em ser um padeiro mundialmente famoso.

Podemos executar o seguinte comando para analisar os dois arquivos com diff e produzir um script para criar um arquivo idêntico a file2.txt a partir do conteúdo de file1.txt :

diff -e arquivo1.txt arquivo2.txt

… e a saída ficará assim:

  5c
 Ela olhava para as nuvens e sonhava em ser um padeiro mundialmente famoso.
 .
 2,3c
 Ela tinha cabelos ruivos.
 Ela adorava biscoitos de chocolate mais do que tudo.
 .

Observe que as alterações estão listadas na ordem inversa: as alterações mais próximas ao final do arquivo são listadas primeiro e as alterações mais próximas ao início do arquivo são listadas por último. Esse pedido é para preservar a numeração das linhas; se fizermos as alterações no início do arquivo primeiro, isso poderá alterar os números de linha posteriormente no arquivo. Portanto, o script começa no final e funciona ao contrário.

Aqui, o script está informando o programa de edição: “mude a linha 5 para (a linha seguinte) e altere as linhas 2 a 3 para (as duas linhas seguintes)”.

Em seguida, devemos salvar o script em um arquivo. Podemos redirecionar a saída diff para um arquivo usando o operador > , assim:

  diff -e arquivo1.txt arquivo2.txt> my-ed-script.txt

Este comando não exibirá nada na tela (a menos que haja um erro); em vez disso, a saída é redirecionada para o arquivo my-ed-script.txt . Se my-ed-script.txt não existir, ele será criado; se já existir, será substituído .

Se agora verificarmos o conteúdo de my-ed-script.txt com o comando cat …

  gato my-ed-script.txt

… veremos o mesmo script que vimos exibido acima.

Ainda falta uma coisa: precisamos do script para dizer ao ed para realmente escrever o arquivo. Tudo o que está faltando no script é o comando w , que gravará as alterações. Podemos adicionar isso ao nosso script repetindo a letra ” w ” e usando o operador >> para adicioná-lo ao nosso arquivo. (O operador >> é semelhante ao operador > . Ele redireciona a saída para um arquivo, mas, em vez de sobrescrever o arquivo de destino, é anexado ao final do arquivo.) O comando se parece com o seguinte:

  eco "w" >> meu-ed-script.txt

Agora, podemos verificar se nosso script foi alterado executando o comando cat novamente:

  gato my-ed-script.txt
  5c
 Ela olhava para as nuvens e sonhava em ser um padeiro mundialmente famoso.
 .
 2,3c
 Ela tinha cabelos ruivos.
 Ela adorava biscoitos de chocolate mais do que tudo.
 .
 W

Agora, nosso script, quando emitido para ed , fará as alterações e gravará as alterações no disco.

Então, como é que vamos fazer isso?

Podemos emitir esse script para edição com o seguinte comando, dizendo para substituir o arquivo original. O traço (”  “) instrui o ed a ler da entrada padrão e o operador < direciona nosso script para essa entrada. Em essência, o sistema insere o que estiver em nosso script como entrada para o programa de edição. O comando fica assim:

  ed - arquivo1.txt <meu-ed-script.txt

Este comando não exibe nada, mas se observarmos o conteúdo do nosso arquivo original …

  cat file1.txt
  Era uma vez uma garota chamada Perséfone.
 Ela tinha cabelos ruivos.
 Ela adorava biscoitos de chocolate mais do que tudo.
 Ela gostava de sentar ao sol com sua gata, Daisy.
 Ela olhava para as nuvens e sonhava em ser um padeiro mundialmente famoso.

… podemos ver que o arquivo1.txt agora corresponde exatamente ao arquivo2.txt .

Aviso! Neste exemplo, ed substituiu o conteúdo do nosso arquivo original, file1.txt . Depois de executar o script, o texto original de file1.txt desaparece. Portanto, certifique-se de entender o que está fazendo antes de executar esses comandos!

Opções de diff comumente usadas

Aqui estão algumas opções diff úteis para anotar:

-bIgnore quaisquer alterações que alterem apenas a quantidade de espaço em branco (como espaços ou tabulações).
-WIgnore completamente os espaços em branco.
-BIgnore linhas em branco ao calcular diferenças.
-yExibe a saída em duas colunas.

Estas são apenas algumas das opções de diferenças mais usadas. A seguir, é apresentada uma lista completa das opções diff e suas funções.

Sintaxe

  diff [ OPÇÃO ] ... ARQUIVOS

Opções

–normalEmita um diff “normal”, que é o padrão.
-q , –briefProduza saída somente quando os arquivos diferirem. Se não houver diferenças, não produza nada.
-s–report-identical-filesRelate quando dois arquivos são iguais.
-c , -C NUM , –context [ = NUM ]Forneça NUM (padrão 3 ) linhas de contexto.
-u-U NUM–unified[=NUM]Forneça NUM (padrão 3 ) linhas de contexto unificado.
-e , –edSaída de um script ed .
-n , –rcsSaída de um formato RCS diff.
-y–side by sideFormate a saída em duas colunas.
-W , –width = NUMSaída na maioria das colunas de impressão NUM (padrão 130 ).
–left-columnSaída apenas a coluna esquerda de linhas comuns.
–suppress-common-linesNão produza linhas comuns entre os dois arquivos.
-p–show-c-functionPara arquivos que contêm código C, mostre também cada alteração de função C.
-F , –show-function-line = REMostrar a linha mais recente correspondente à expressão regular RE .
–label LABELAo exibir a saída, use o rótulo LABEL em vez do nome do arquivo. Esta opção pode ser emitida mais de uma vez para vários rótulos.
-t , –expand-tabsExpanda guias para espaços na saída.
-T , – guia inicialPara alinhar as guias, adicione uma guia, se necessário.
–tabsize = NUMDefina uma tabulação como NUM (padrão 8 ) colunas.
–suppress-blank-emptySuprima espaços ou tabulações antes das linhas de saída vazias.
-l , –paginatePasse a saída pelo pr para paginar .
-r , –recursiveCompare recursivamente todos os subdiretórios encontrados.
-N–new-fileSe um arquivo especificado não existir, execute o diff como se fosse um arquivo vazio.
–unidirectional-new-fileO mesmo que -n , mas só se aplica ao primeiro arquivo.
–ignore-file-name-caseIgnore maiúsculas e minúsculas ao comparar nomes de arquivos.
–no-ignore-file-name-caseConsidere o caso ao comparar nomes de arquivos.
-x , –exclude = PATExcluir arquivos que correspondam ao padrão de nome de arquivo PAT .
-X–exclude-from=FILEExcluir arquivos que correspondam a qualquer padrão de nome de arquivo no arquivo FILE .
-S , –starting-file = ARQUIVOComece com o arquivo FILE ao comparar diretórios .
–from-file = FILE1Compare FILE1 a todos os operandos ; FILE1 pode ser um diretório.
–to-file=FILE2Compare todos os operandos ao FILE2 ; FILE2 pode ser um diretório.
-i , –ignore-caseIgnore as diferenças entre maiúsculas e minúsculas no conteúdo do arquivo.
-E , –ignore-tab-expansionIgnore as alterações devido à expansão da guia .
-b , –ignore-space-changeIgnore as alterações na quantidade de espaço em branco .
-w , –ignore-all-spaceIgnore todo o espaço em branco.
-B , –ignore-blank-linesIgnore as alterações cujas linhas estão todas em branco.
-I , –ignore-matching-lines = REIgnore as alterações cujas linhas correspondem à expressão regular RE .
-a , –textTrate todos os arquivos como texto.
–strip-trailing-crRetorno de carro à direita da faixa na entrada.
-D , –ifdef = NAMEArquivo de saída mesclado com ” #ifdef NAME ” diffs.
 GTYPE -group -format = GFMTFormate grupos de entrada GTYPE com GFMT .
–line-format = LFMTFormate todas as linhas de entrada com LFMT .
 LTYPE -line-format = LFMTFormate as linhas de entrada LTYPE com LFMT .

Essas opções de formato fornecem controle refinado sobre a saída do diff , generalizando -D / –ifdef .

LTYPE é antigo , novo ou inalterado .

GTYPE pode ser qualquer um dos valores LTYPE ou o valor alterado .

GFMT (mas não LFMT ) pode conter:

% <linhas de FILE1
%>linhas de FILE2
% =linhas comuns a FILE1 e FILE2 .
% [  ] [ LARGURA ] [ . PREC ]] { doxX } CARTAespecificação printf- style para LETTER

LETRA s são as seguintes para o novo grupo, em minúsculas para o grupo antigo:

FNúmero da primeira linha.
LNúmero da última linha
NNúmero de linhas = L – F + 1.
EF – 1
ML + 1
% ( A = B ? T : E )Se A for igual a B, então T mais E.

LFMT (apenas) pode conter:

%LConteúdo da linha.
%lConteúdo da linha, excluindo qualquer nova linha à direita.
% [  ] [ LARGURA ] [ . PREC ]] { doxX } nespecificação printf- style para o número da linha de entrada.

GFMT e LFMT podem conter:

%%Um % literal .
% c ‘ C O único caractere C.
% c ‘\ OOO’O personagem com código octal OOO.
CO caractere C (outros caracteres se representam).
-d , –minimalTente encontrar um conjunto menor de alterações.
–horizon-lines = NUMMantenha NUM linhas do prefixo e sufixo comuns.
–speed-large-filesSuponha arquivos grandes e muitas pequenas alterações espalhadas.
–helpExiba uma mensagem de ajuda e saia.
-v , –versionInformações de versão de saída e saída.

FILES assume o formato ” FILE1 FILE2 ” ou ” DIR1 DIR2 ” ou ” DIR FILE …” ou ” FILE … DIR “.

Se as opções –from-file ou –to-file forem fornecidas, não haverá restrições em FILE (s). Se um arquivo é um traço (”  “), o diff lê da entrada padrão .

O status de saída é 0 se as entradas forem iguais, 1 se diferente ou 2 se o diff encontrar algum problema.

Exemplos

Aqui está um exemplo do uso do diff para examinar as diferenças entre dois arquivos lado a lado usando a opção -y , considerando os seguintes arquivos de entrada:

file1.txt:

  maçãs
 laranjas
 kiwis
 cenouras

file2.txt:

  maçãs
 kiwis
 cenouras
 toranjas
  diff -y arquivo1.txt arquivo2.txt

Resultado:

  maçãs maçãs
 laranjas <
 kiwis kiwis
 cenouras cenouras
                 > toranjas

E, como prometido, aqui está um exemplo do uso do diff para comparar dois diretórios:

  diff dir1 dir2

Resultado:

  Somente em dir1: tab2.gif
 Somente no dir1: tab3.gif
 Somente em dir1: tab4.gif
 Somente no dir1: tape.htm
 Somente no dir1: tbernoul.htm
 Somente no dir1: tconner.htm
 Somente no dir1: tempbus.psd

bdiff – identifique as diferenças entre dois arquivos muito grandes.
cmp – Compare dois arquivos byte por byte.
comm – Compare dois arquivos classificados linha por linha.
dircmp – Compare o conteúdo de dois diretórios, listando arquivos exclusivos.
ed – Um simples editor de texto.
pr – Formate um arquivo de texto para impressão.
ls – lista o conteúdo de um diretório ou diretórios.
sdiff – Compare dois arquivos, lado a lado.

18 de novembro de 2019

Sobre nós

A Linux Force Brasil é uma empresa que ama a arte de ensinar. Nossa missão é criar talentos para a área de tecnologia e atender com excelência nossos clientes.

CNPJ: 13.299.207/0001-50
SAC:         0800 721 7901

[email protected]

Comercial  Comercial: (11) 3796-5900

Suporte:    (11) 3796-5900
[email protected]

Copyright © Linux Force Security  - Desde 2011.