Localizando novas linhas em um arquivo comparado com outro [duplicado]

3

Eu preciso comparar dois arquivos txt. Cada linha dos dois arquivos txt contém entradas. Uma entrada por linha. O novo arquivo contém entradas que o antigo não possui. Eu tentei usar diff e vimdiff , mas isso não funciona porque as linhas podem estar em ordem diferente.

Por exemplo:

ANTIGO ARQUIVO

alpha
beta
gama

NOVO ARQUIVO

delta
omega
beta
alpha
gama
rho
phi

diff e vimdiff compara a linha 1 com a linha 1, a linha 2 com a linha 2, etc e, mesmo se eu classificar os dois arquivos, a comparação não terá êxito porque posso ter novos itens entre as versões classificadas, como "alfa , beta, rho "versus" alfa, beta, gama, rho ".

Como faço para obter uma lista de entradas que o novo arquivo tem que o antigo não possui?

    
por SpaceDog 02.11.2014 / 15:04

5 respostas

3
start cmd:> awk 'FNR == NR { oldfile[$0]=1; }; 
  FNR != NR { if(oldfile[$0]==0) print; }' file1 file2
delta
omega
rho
phi
    
por 02.11.2014 / 15:33
3

Eu usaria grep

grep -Fxvf oldfile newfile

-F : use o modo de string fixo (sem metacaracteres)

-x : corresponde à linha inteira (não a uma substring)

-f oldfile : leia as sequências a serem correspondidas a partir de oldfile

-v : inverte a correspondência, ou seja, as sequências de impressão NÃO são encontradas em oldfile

    
por 02.11.2014 / 15:50
2

Um comando awk mais curto:

awk 'NR==FNR{a[$0];next}!($0 in a)' file1 file2

Se file1 puder estar vazio, substitua NR==FNR por FILENAME==ARGV[1] .

grep -Fxvf file2 file1 é lento para arquivos grandes:

$ jot -r 10000 1 100000 >file1;jot -r 10000 1 100000 >file2
$ time awk 'NR==FNR{a[$0];next}!($0 in a)' file1 file2 >/dev/null
0.015
$ time grep -Fxvf file2 file1 >/dev/null
36.758
$ time comm -13 <(sort file1) <(sort file2)>/dev/null
0.173

Se você precisar remover linhas repetidas, use

awk 'NR==FNR{a[$0];next}!b[$0]++&&!($0 in a)' file1 file2

ou

comm -13 <(sort file1) <(sort -u file2)
    
por 03.11.2014 / 23:47
0

Se você não se importar com a ordem das entradas, classifique os dois arquivos e depois use comm .

comm -13 <(sort old.txt) <(sort new.txt)

Ou se o seu shell não tiver substituição de processo:

sort old.txt >sorted.old.txt
sort new.txt >sorted.new.txt
comm -13 sorted.old.txt sorted.new.txt

Se a ordem das inscrições for importante, você pode usar grep com as opções certas : -Fx para corresponder exatamente a linhas completas, -v para excluir linhas correspondentes e -f para ler um arquivo contendo os padrões a serem excluídos.

grep -Fxv -f old.txt new.txt
    
por 02.11.2014 / 15:52
0

No caso, se você precisar da maneira python de fazê-lo.

#!/usr/bin/env python3.4


oldfp = open('/tmp/tmp.Q3JiYGY6fs/oldfile')
newfp = open('/tmp/tmp.Q3JiYGY6fs/newfile')


old = set([ x.strip() for x in oldfp.readlines() ])
new = set([ x.strip() for x in newfp.readlines() ])

print('Lines that are present only in newfile are \n{}\n\n{} '.format(42*'-', '\n'.join(list(new - old))))

E a saída será

Lines that are present only in newfile are 
------------------------------------------

phi
rho
omega
delta
    
por 04.11.2014 / 14:49