Combine dois arquivos com ids duplicados

1

Eu tenho dois arquivos com ids duplicados. Um arquivo tem 150 ids, mas como todos eles existem como duplicatas, há 300 ids. O arquivo 2 tem 1.500 ids, mas como todos os ids existem em duplicatas, ele possui 3.000 IDs. Eu quero coincidir com a primeira ocorrência de cada id no arquivo um com primeira ocorrência de id no arquivo 2 e segunda ocorrência do mesmo id com segunda precisão de id no arquivo 2. Se o valor de id na 2ª coluna for igual a imprimir corresponderá de outro modo uma incompatibilidade.

File1 :

1 12
1 13
2 15
2 16
4 15 
4 18

File2 :

1 13
1 13
2 15
2 17
3 12
3 12
4 15 
4 18
5 14
5 14

Saída desejada (Id, col 2 do arquivo 1, col 2 do arquivo 2, correspondência ou incompatibilidade):

1 12 13 mismatch
1 13 13 match
2 15 15 match
2 16 17 mismatch
4 15 15 match
4 18 18 match
    
por limd 03.07.2017 / 07:16

3 respostas

1

Python3

#!/usr/bin/env python3

import sys

def make_id_dict(f):
  d = {}
  for line in open(f):
    k, v = line.split()
    if k in d:
      d[k] += [ v ]
    else:
      d[k] = [ v ]
  return d


filename1 = sys.argv[1]
filename2 = sys.argv[2]

dict1 = make_id_dict(filename1)
dict2 = make_id_dict(filename2)

for key in sorted(dict1):
  for i, value1 in enumerate(dict1[key]):
    value2 = dict2[key][i]
    if value1 == value2:
      result = 'match'
    else:
      result = 'mismatch'
    print(key, value1, value2, result)

Salvar como script match-files-by-ids.py , em seguida, chamar:

$ python3 match-files-by-ids.py File1 File2
1 12 13 mismatch
1 13 13 match
2 15 15 match
2 16 17 mismatch
4 15 15 match
4 18 18 match
    
por wjandrea 03.07.2017 / 08:06
0

Se os arquivos:

  • são classificados; e
  • Cada
  • contém exatamente zero ou duas ocorrências de um determinado índice

então, se nós join deles, receberemos quatro "correspondências" para cada ID que pode ser combinado, ou seja,

1st IDn from File1 against 1st IDn from File2
1st IDn from File1 against 2nd IDn from File2
2nd IDn from File1 against 1st IDn from File2
2nd IDn from File1 against 2nd IDn from File2

e assim por diante. Linhas não pareadas serão ignoradas (a menos que usemos a opção -a ). Podemos então escolher a primeira e a quarta linha de cada grupo de jogos e comparar seus respectivos segundos campos:

$ join File1 File2 | 
  awk '!((NR-1)%4 && NR%4) { = == ? "match" : "mismatch"; print}'
1 12 13 mismatch
1 13 13 match
2 15 15 match
2 16 17 mismatch
4 15 15 match
4 18 18 match

onde (NR-1)%4 é zero para linhas 1,5,9 etc. e NR%4 é zero para linhas 4,8 etc. assim, e-ing e inversão são verdadeiros para 1,4; 5,9 ...

    
por steeldriver 03.07.2017 / 15:17
0

Aqui está uma solução awk :

awk '
  NR==FNR {
    if ( in a) 
      b[]=; 
    else 
      a[]=; 
    next;
  } 
  ( in a) {
    print , a[], ,  == a[] ? "match" : "mismatch";
    delete a[];
    next;
  }
  ( in b) {
    print , b[], ,  == b[] ? "match" : "mismatch";
  }' File1 File2

Teste:

$ awk '
  NR==FNR {if ( in a) b[]=; else a[]=; next} 
  ( in a) {print , a[], ,  == a[] ? "match" : "mismatch"; delete a[]; next; }
  ( in b) {print , b[], ,  == b[] ? "match" : "mismatch";}
' File1 File2
1 12 13 mismatch
1 13 13 match
2 15 15 match
2 16 17 mismatch
4 15 15 match
4 18 18 match
    
por steeldriver 03.07.2017 / 22:13