Supondo que os arquivos estejam todos ordenados e que estamos usando um shell que entenda as substituições do processo (como bash
):
$ join -t . -v 1 -o 0 <( join -t . a.txt b.txt ) c.txt
c
ou, para outras camadas,
$ join -t . a.txt b.txt | join -t . -v 1 -o 0 - c.txt
c
Isso usa join
duas vezes para realizar junções relacionais entre os arquivos. Os dados são interpretados como campos delimitados por pontos (com -t .
).
A junção entre a.txt
e b.txt
é direta e produz
a.up
b.up
c.up
Estas são todas as linhas dos dois arquivos cujo primeiro campo delimitado por ponto ocorre nos dois arquivos. A saída consiste no campo de junção ( a
, b
, c
) seguido pelos outros campos de ambos os arquivos (somente b.txt
possui dados adicionais).
A segunda junção é um pouco mais especial. Com -v 1
, pedimos para ver as entradas no primeiro arquivo (o resultado intermediário acima) que não podem ser emparelhadas com nenhuma linha no segundo arquivo, c.txt
. Além disso, pedimos apenas para ver o próprio campo de associação ( -o 0
). Sem o -o
flag, obteríamos c.up
como resultado.
Se os arquivos não forem classificados, cada ocorrência de um nome de arquivo file
poderá ser substituída por <( sort file )
no comando.