Una dois arquivos, cada um com duas colunas, incluindo linhas não correspondentes

4

Estou tentando combinar e mesclar dois conjuntos de dados classificados, um conjunto por arquivo. Cada arquivo contém duas colunas: o campo-chave e o valor associado. A saída resultante deve conter três colunas: o campo-chave, o valor (se houver) do primeiro arquivo e o valor (se houver) do segundo arquivo. Preciso incluir linhas de dados que não são correspondidas.

Primeiro arquivo "john"

apple,green
cherry,red
orange,orange

Segundo arquivo "jane"

apple,red
banana,yellow
cherry,yellow
kiwi,green

Resultado desejado

apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange,

Eu pensei inicialmente que este era um trabalho trivial para join

LC_ALL=C join -j1 -a1 -a2 -t',' john jane

Mas o resultado do -a1 -a2 coloca o valor sem correspondência sempre na segunda coluna:

apple,green,red
banana,yellow
cherry,red,yellow
kiwi,green
orange,orange

Eu preciso poder ver de qual arquivo de origem o valor sem correspondência é originado, de preferência por ter esses valores na segunda ou terceira coluna apropriada do arquivo de resultados, mas não consigo descobrir uma maneira simples de alcançar isso sem descer Construções awk ... getline() type.

Alguma sugestão, por favor?

    
por roaima 05.04.2016 / 23:43

3 respostas

7

Você quer -o auto :

join -t, -j 1 -a 1 -a 2 -o auto john jane

De man join :

-o FORMAT
       obey FORMAT while constructing output line
If FORMAT is the keyword 'auto', then the first line of  each  file  determines  the  number  of fields output for each line.

Ou melhor explicado em GNU Coreutils: participar da invocação :

‘-o auto’

If the keyword ‘auto’ is specified, infer the output format from the first line in each file. This is the same as the default output format but also ensures the same number of fields are output for each line. Missing fields are replaced with the -e option and extra fields are discarded.

% cat john 
apple,green
cherry,red
orange,orange
% cat jane 
apple,red
banana,yellow
cherry,yellow
kiwi,green
% join -t, -j 1 -a 1 -a 2 -o auto john jane
apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange,
    
por 06.04.2016 / 00:04
4

Você pode especificar explicitamente o formato de saída

LC_ALL=C join -o0,1.2,2.2 -j1 -a1 -a2 -t',' john jane

que produz

apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange,

A principal coisa aqui é que o campo de junção também pode ser referenciado no formato de saída usando 0 , o que é bastante útil no contexto de linhas não parciais

    
por 06.04.2016 / 00:02
1

Esse comando quase faz isso; omite uma vírgula final se a chave aparecer apenas no arquivo1. Não tem tempo para depurar totalmente agora:

awk -F, 'BEGIN{OFS=","} FNR==NR{val[$1]=$2;next} {val[$1]=val[$1] "," $2}END{for (key in val) {print key, val[key]}}' john jane

Saída:

apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange
    
por 06.04.2016 / 00:00

Tags