Eu tenho dois arquivos com um valor de chave primária como primeiro campo e valores correspondentes como os campos restantes, e alguns valores de chave primária estão faltando em um deles, mas estão presentes em outro e vice-versa:
$ cat jointest1.txt jointest2.txt
a 1
b 2
d 4
e 5
a 10
b 11
c 12
d 13
Eu esperaria uma saída que mesclasse esses arquivos de acordo com uma chave primária, substituindo ou não os valores ausentes, como:
$ joinmerge jointest1.txt jointest2.txt
a 1 10
b 2 11
c - 12
d 4 13
e 5 -
A capacidade de substituir valores ausentes por travessões ou algo assim é opcional.
Eu tentei join
, mas diz que meus arquivos não estão classificados corretamente:
$ join jointest1.txt jointest2.txt
a 1 10
b 2 11
join: file 2 is not in sorted order
d 4 13
Qual comando devo usar em vez disso?
Responder1
Experimente o seguinte:
> join -e- -a1 -a2 jointest1 -o 0 1.1 1.2 2.1 2.2 jointest2
a a 1 a 10
b b 2 b 11
c - - c 12
d d 4 d 13
e e 5 - -
ou
> join -e- -a1 -a2 jointest1 -o 0 1.2 2.2 jointest2
a 1 10
b 2 11
c - 12
d 4 13
e 5 -
Não tenho certeza se/como é possível conseguir o mesmo sem a opção -o. A opção -o diz: primeiro imprima o campo de junção e depois o campo não. 2 do arquivo 1, depois campo 2 do arquivo 2. É meio triste que você precise saber o formato dos arquivos para que os campos vazios funcionem.
Responder2
Qual implementação join
você está usando? Com join (GNU coreutils) 5.97
, posso usar
[0 1021] ~/temp/jointest % join -a1 -a2 jointest1.txt jointest2.txt
a 1 10
b 2 11
c 12
d 4 13
e 5
e a junção "simples" também funciona (mas omite c e e). Existe uma -e
opção que supostamente permite escolher o marcador para campos vazios, mas parece estar quebrado na minha versão e preenche apenas o caso e, não o caso c.
Responder3
Eu escrevi uma ferramenta Perl exatamente para esse problema de chave e valor:
Emparelhando as linhas certas: qualquer número de arquivos. Também está disponível atravésGitHub.
Para executá-lo, você digita:
merge -k -e "-" jointest1.txt jointest2.txt