Compare dois arquivos: linhas presentes em um, não no outro, por uma comparação de coluna

6

Eu preciso comparar dois arquivos. Coluna 1 é o mesmo em ambos os arquivos. Coluna 2 é o que eu quero comparar: Eu quero todas as linhas no arquivo 1 que não estão no arquivo 2 ao comparar a coluna 2. A coluna 3 é diferente em ambos os arquivos, mesmo para as linhas onde as colunas 1 e 2 são idênticas. Não consigo remover a coluna 3 porque, como saída, quero as linhas do arquivo 1, incluindo essa coluna.

Aqui está um exemplo:

Arquivo 1

21  12340   3
21  12341   7
21  12342   2
21  12343   89
21  12349   7

Arquivo 2

21  12340   55
21  12341   7
21  12343   89
21  12344   7
21  12346   88
21  12347   3
21  12348   37

Meu resultado seria:

21  12342   2
21  12349   7
    
por newbi 19.08.2012 / 17:19

4 respostas

8

join requer que os arquivos sejam pré-classificados, pois eles estão nos args da amostra para join ), então se você precisar manter a seqüência da saída , será necessária uma abordagem diferente . Observe que ele não tenta manter a largura do espaçamento de campo original.

join -1 2 -2 2 -v 1 <(sort file1) <(sort file2)

saída

21 12342 2
21 12349 7
    
por 20.08.2012 / 00:54
6

Uma awk solution:

awk '
    FNR == NR {
        data[ $2 ] = 1;
        next;
    }
    FNR < NR {
        if ( ! ($2 in data) ) {
            print $0;
        }
    }
' file2 file1

Resultado:

21  12342   2
21  12349   7
    
por 19.08.2012 / 20:06
3

Usando o Python no shell bash:

paddy$ python -c 'import sys
with open(sys.argv[2]) as f: file2col2 = {line.split()[1] for line in f}
with open(sys.argv[1]) as f: print("".join(line for line in f 
                                           if line.split()[1] not in file2col2))
' file1.tmp file2.tmp
21  12342   2
21  12349   7

paddy$ 
    
por 28.08.2012 / 23:10
2

Usando egrep e awk :

egrep -v -f <(awk '{printf "^%s[ ]+%s[ ]+\n", $1, $2}' file2) file1

O awk bit dentro de <() gera padrões com base no conteúdo de file2 . O egrep usa esses padrões para corresponder às linhas em file1 , com -v invertendo a correspondência, imprimindo apenas as linhas que não correspondem.

    
por 19.08.2012 / 18:24