Como fazer o comando diff ignorar certas linhas do segundo arquivo (bash)?

2

Por exemplo:

arquivo1.txt:

I need to buy apples.
I need to run the laundry.
I need to wash the dog.
I need to get the car detailed.

arquivo2.txt

I need to buy apples.
I need to run the laundry.
I need to wash the car.
I need to get the car detailed.

file3.txt

I need to wash the car.

Se eu fizer diff file1.txt file2.txt , as instruções presentes em file3.txt devem ser ignoradas pelo comando diff se estiverem presentes no arquivo2.txt. Então, neste caso, não deve haver diferença.

Usar o sinalizador de ignorar ( diff -I "$line" ) não ajudará, pois encontra padrão nos dois arquivos.

Como posso fazer isso?

    
por Menon 09.04.2015 / 12:50

4 respostas

3

Uma solução alternativa seria remover as linhas correspondentes e depois diferenciá-las. Isso quer dizer que tanto file1 quanto file2 seriam semelhantes:

I need to buy apples.
I need to run the laundry.

I need to get the car detailed.

Você pode fazer isso usando uma combinação de grep , perl e sed :

$ lines_to_ignore=$(grep -nFf file3 file2 | perl -pe 's|^(\d+):.*|$1s/.//g;|')
$ echo $lines_to_ignore 
3s/.//g;
$ diff <(sed "$lines_to_ignore" file1) <(sed "$lines_to_ignore" file2)        
$ echo $?
0
  • Eu uso grep para obter as linhas correspondentes (junto com números de linha) em file2
  • Em seguida, uso perl para obter os números de linha da grep output e fazer os comandos sed deles ( Ns/.//g exclui todos os caracteres na linha N).
  • Depois, uso a substituição de processo para alimentar o resultado de sed executando esses comandos nos arquivos para diff .
por 09.04.2015 / 13:26
1

Você pode combinar diff e combine aqui:

$ diff file1.txt <(combine file2.txt NOT file3.txt)
3d2
< I need to wash the dog.

Atualizado para refletir as alterações no OP.

    
por 09.04.2015 / 13:03
1

use a opção grep para filtrar a linha do arquivo

$ diff f1 f2
3c3
< I need to wash the dog.
---
> I need to wash the car.
$ diff <( grep -v -f f3 -x f1) <( grep -v -f f3 -x f2)
3d2
< I need to wash the dog.

onde

  • <( ) é uma sintaxe bash para criar um arquivo temporário
  • no grep
    • -x corresponde à mentira inteira
    • -f f3 toma o patterm do arquivo f3
    • -v mostra um padrão incomparável
por 09.04.2015 / 13:46
0

diff pode não ser a ferramenta certa. Parece que você precisa usar comm , que classifica cada linha como estando em um arquivo, o outro arquivo ou comum a ambos.

A principal limitação, no entanto, é que comm requer que os dois arquivos de entrada sejam classificados

    
por 09.04.2015 / 14:33