Eu tenho dois arquivos simples A e B. A é um arquivo grande com milhões de registros e B deve ser um subconjunto de A. A tem 20 colunas com uma chave exclusiva e B tem 5 colunas com a mesma chave exclusiva. Você poderia me informar como comparar B com A e descobrir se os registros presentes no arquivo B também estão presentes no Arquivo A e possuem os mesmos dados nas respectivas colunas.
Responder1
Criei dois arquivos para demonstrar meus comandos
file1
:
1 a1 b1 c1 d1 e1
2 a2 b2 c2 d2 e2
3 a3 b3 c3 d3 e3
4 a4 b4 c4 d4 e4
5 a5 b5 c5 d5 e5
file2
:
2 b2 c2 e2
4 b4 c4 xx
5 b5 c5 e5
A primeira coluna é a chave exclusiva. As colunas comuns são column b
e c
. e
As linhas comuns são 2
, 4
e 5
. Row 4
tem um valor diferente em column e
.
Aqui está o comando com saída:
$ comm -1 -3 <(cut -d' ' -f1,3,4,6 file1) file2
4 b4 c4 xx
Se os arquivos ainda não estiverem classificados, você pode fazer assim:
$ comm -1 -3 <(cut -d' ' -f1,3,4,6 file1 | sort) <(sort file2)
Explicação:
cut -d' ' -f1,3,4,6 file1
Imprima os campos número 1, 3, 4 e 6 do arquivo. Os campos são separados por espaço. Se os campos estiverem separados por vírgulas, use cut
assim:cut -d','
<( ... )
comm -1 -3 file1 file2
Imprime linhas exclusivas do arquivo2.
Ressalvas:
cut
terá problemas se o caractere separador puder ocorrer como um caractere em um campo.
Por exemplo:
"field1","field2,stillfield2","field3"
cut
não entenderá que a vírgula "field2,stillfield2"
faz parte do campo.
Se seus arquivos são assim, talvez seja melhor usar uma linguagem de programação com manipulação de CSV integrada. Por exemploPitão.
Responder2
Se os arquivos tiverem colunas diferentes, como você disse, a maneira mais fácil seria escrever um pequeno programa usando uma linguagem de sua escolha. diff
e comm
não será de muita ajuda se a estrutura das linhas nos arquivos não for idêntica.
Responder3
Além da comm
solução que diff
você pode usar grep
para isso.
Supondo que seus dados relevantes sejam as colunas 1,3 e 10 no arquivo A e 1,2 e 3 no arquivo B. Usamos cut
para selecionar as colunas de A, usamos isso como o arquivo de correspondência de palavras-chave e verificamos inversamente sua presença no arquivo B . Se o arquivo B tiver uma linha que não esteja presente nas linhas correspondentes extraídas do arquivo A, elas serão exibidas. Se todos corresponderem, não há saída (já que B supostamente é um subconjunto de A)
grep -wvf <( cut -f1,3,10 fileA ) fileB
Ou se o arquivo B tiver mais do que três colunas:
grep -wvf <( cut -f1,3,10 fileA ) <( cut -f1,2,3 fileB )