Combinando dois arquivos para primeira linha semelhante

2

Eu tenho 2 conjuntos de arquivos.

O arquivo um contém ID's ex:

1111
2222
6666
3333
4444

O arquivo dois contém o ID e o nome de usuário:

1873 Neil
1111 Roger
7632 Tim
3333 Oscar
8723 Greg
4444 Roy
6666 Patrick

Eu quero extrair o ID e o nome de usuário, mas somente aqueles que possuem o mesmo ID que no arquivo 1. Eu fiz o% normalgrep -f file1 file2, em dois arquivos de teste que fiz, com poucos ID's como os que acabei de postar. No entanto, quando eu aplico isso aos dois arquivos corretos, onde file1 contém 3500 ID's e File2 contém 12000 ID's + Username, em vez de extrair as 3500 linhas que ocorrem nos dois arquivos, ele extrai 12000 linhas. No entanto, com os 2 arquivos de teste e alguns IDs falsos, ele extrairá apenas os IDs corretos e deixará os outros.

Alguma dica sobre o que está errado?

    
por Arne 14.02.2013 / 13:36

2 respostas

4

Tente fazer isso usando em vez de grep . ser mais adequado:

$ join  <(sort file1) <(sort file2)

1111 Roger
3333 Oscar
4444 Roy
6666 Patrick

Se o seu shell não tiver substituições de processo <( ) , você pode fazer:

sort file1 > new_file1
sort file2 > new_file2
join new_file1 new_file2

Doc disse:

join writes to standard output a line for each pair of input lines that have identical join fields.

Consulte o link

Notas:

O arquivo precisa ser classificado na chave de classificação para que join funcione corretamente. É por isso que usamos alguns descritores de arquivo em segundo plano usando substituições de processo Consulte o link ou o link para um uso comum.

    
por 14.02.2013 / 13:44
0

grep corresponde a linhas em que um nome de usuário é igual a um id. join limita corretamente a correspondência para o primeiro campo, mas requer entrada classificada. Dependendo da entrada awk pode ser uma boa alternativa:

awk 'FNR == NR { ids[$1]++; next } ids[$1]' ids users

Ou mais legível:

awk 'FNR == NR { ids[$1]; next } $1 in ids' ids users

Saída:

1111 Roger
3333 Oscar
4444 Roy
6666 Patrick

Explicação

O programa awk é dividido em duas partes: uma avaliada para o primeiro arquivo e outra avaliada para o segundo arquivo.

O primeiro bloco é avaliado apenas para o primeiro arquivo e salva os IDs no array ids . Quando esses IDs são encontrados ao ler users , o bloco padrão é invocado ( {print $0} ).

    
por 14.02.2013 / 15:27