Mesclar arquivos usando uma coluna comum

8

Eu tenho dois arquivos dos quais eu quero criar um terceiro que contém todas as informações.

arquivo 1:

a 111 
b 222 
c 333 
d 666 
e 777 

arquivo 2:

111 x1  
222 x2
333 x3
444 x4 
555 x5 
666 x6 
777 x7 
888 x8

Gostaria de combiná-los da seguinte forma:

111  x1  a
222  x2  b
333  x3  c
444  x4  0
555  x5  0
666  x6  d
777  x7  e
888  x8  0

Nota:

A segunda coluna do arquivo 1 é um subconjunto da primeira coluna do arquivo 2

gforce89
fonte

Respostas:

7

O joincomando faz quase o que você precisa, se os arquivos são classificados como em suas amostras:

join -12 -a2 file1 file2 -o2.1,2.2,1.1

Você só precisa adicionar os zeros às linhas sem correspondência. Você pode usar a -eopção para isso:

join -12 -a2 file1 file2  -o2.1,2.2,1.1 -e0
choroba
fonte
se você adicionar o -e0não precisa de perl :)
LilloX
@LilloX: Verdade, obrigado. Eu tentei, mas falhei (erro de digitação).
choroba
13

Usando junção:

join -1 1 -2 2 -a1 -e0 -o'0,1.2,2.1' file2 file1

O comando join une as linhas de dois arquivos que compartilham um campo de dados comum. Nesse caso: Una o arquivo2 e o arquivo1 usando o campo 1 ( -1 1) do arquivo2 e o campo 2 ( -2 2) do arquivo1.

A saída será: "campo unido, campo 2 do arquivo2, campo 1 do arquivo1" ( -o'0,1.2,2.1'), se houver um campo ausente, coloque 0 ( -e0)

Se um dos dois arquivos tiver mais registros, adicione-os (nesse caso, arquivo2) ( -a1)

Por favor, consulte a página de manual do comando join

LilloX
fonte
Boa. Você poderia adicionar um pouco de explicação?
Lety
Claro, Atualizado :)
LilloX
5

Um pouco de awkmágica:

awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0}; \
    printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}' \
    file1 file2

ou

awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0};
    print $1,$2,a[$1]}' file1 file2

Resultado

111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0

Explicação

  • FNR==NR{a[$2]=$1;next}

    Executa over file1( FNR==NR) e cria uma estrutura de valor-chave. A chave é a segunda coluna ( $2) de file1, o valor é a primeira coluna ( $1) defile1

  • {if(a[$1]==""){a[$1]=0};print $1,$2,a[$1]}

    Corre file2e

    • if(a[$1]==""){a[$1]=0}

      Se a chave na primeira coluna ( $1) in file2não existir file1, precisamos de um0

    • print $1,$2,a[$1]

      Imprima (usando print) a primeira e a segunda coluna file2e o valor da estrutura de valores-chave com a chave da primeira coluna ( $1) defile2

      ou

    • printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}'

      Imprima (usando printf) a primeira e a segunda coluna de file2e o valor da estrutura de valores-chave com a chave da primeira coluna ( $1) de file2.

      • FS é o separador entre as colunas, retirado do arquivo de entrada

      • "%s%s%s%s%s\n"

        é a formatação para a saída

        • %s - Corda

        • \n - Nova linha

AB
fonte
Você poderia explicar o código?
precisa saber é o seguinte
Claro, resposta atualizada.
AB
1

Usando q :

$ q "select f2.c1, f2.c2, ifnull(f1.c1,0) from file_2.txt f2 LEFT JOIN file_1.txt f1 on f1.c2 = f2.c1 "
111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0

Às vezes, pode ser mais legível dessa maneira.

Vi.
fonte
1
Para quem quer saber, qestá no pacote python3-q-text-as-data(Python 3) e no pacote python-q-text-as-data(Python 2).
kos
Obrigado, mas onde posso obter este qpacote? Eu não parecem ser capazes de instalar qualquer python-q-text-as-dataou python3-q-text-as-data. "E: Não foi possível localizar o pacote python3-q-text-as-data". Meu sistema já instalado python, python2.7, python3, e python3.4.
Paddy Landau
Talvez o pacote seja muito novo e não esteja disponível no seu release de distribuição. Você pode cloná-lo no Github: github.com/harelba/q
Vi.