juntar linhas com base em string em 2 colunas de 2 arquivos

juntar linhas com base em string em 2 colunas de 2 arquivos

Eu tenho um arquivo1 com 3 colunas e um arquivo2 com 4 colunas em um sistema Linux. Como faço para unir os dois arquivos com base na string da coluna 3 do arquivo1 à string da coluna 2 do arquivo2? File2 é um banco de dados grande com muitas entradas. As colunas 3 e 2 de arquivo1 e arquivo2 compartilham respectivamente apenas algumas strings. Gostaria de gerar o arquivo1 com linhas unidas do arquivo2, caso as strings correspondam e gerar um traço para entradas sem correspondências.

arquivo1:

300 100 a101
450 410 a400
670 710 a20
700 610 a340

arquivo2:

b30  a340 tttttttt 456
b500 a200 llllllll 567
b60  a101 uuuuuuuu 344
b40  a50  kkkkkkkk 223

saída:

300 100 a101 b60 a101 uuuuuuuu 344
450 410 a400 -
670 710 a20  -
700 610 a340 b30 a340 tttttttt 456

Responder1

Usando GNU awke GNU join, que são padrão no Linux (podem ou não funcionar com versões não-GNU):

$ join -a1 -1 3 -2 2 <(sort -k3,3 file1) <(sort -k2,2 file2) | 
    awk '$4 == "" { $4 = "-" }; {t=$1; $1=$2; $2=$3; $3=t; print}' |
    sort
300 100 a101 b60 uuuuuuuu 344
450 410 a400 -
670 710 a20 -
700 610 a340 b30 tttttttt 456

O joincomando une arquivo1 e arquivo2 nos campos 3 e 2 respectivamente. Ele usasubstituição de processopara garantir que ambos os arquivos sejam classificados por seus respectivos campos-chave. A -a 1opção é usada para que todas as linhas de file1sejam impressas, mesmo que não correspondam a uma linha de file2.

Infelizmente, joincoloca o campo-chave do arquivo1 no início de cada registro. Isso é corrigido para awkmover os campos de volta à sua ordem original, usando uma variável chamada tcomo detentor temporário para o valor de $1. O script awk também adiciona o caractere traço final no campo $4 se não houver correspondência entre os arquivos (porque joinele próprio não faz isso).

Finalmente, a saída é classificada.

informação relacionada