Mesclar dados de dois arquivos que estão em ordens diferentes.

0

Eu tenho dois arquivos abaixo. Eu preciso aplicar os números de ID do arquivo1 ao arquivo2 correspondendo aos nomes de host correspondentes. Saída desejada também abaixo. Eu prefiro fazer isso com um script bash se possível, mas estou aberto a alternativas.

arquivo1:

ID: 12345, Name: foo1.bar.com
ID: 12346, Name: foo2.bar.com
ID: 12347, Name: foo3.bar.com
ID: 12348, Name: foo4.bar.com
ID: 12349, Name: foo5.bar.com

arquivo2:

foo3.bar.com
foo4.bar.com
foo1.bar.com
foo5.bar.com
foo2.bar.com

saída desejada -

12347 foo3.bar.com
12348 foo4.bar.com
12345 foo1.bar.com
12349 foo5.bar.com
12346 foo2.bar.com

Alguma idéia sobre a melhor maneira de lidar com isso?

    
por Lewie 19.04.2018 / 01:20

2 respostas

3

Crie uma tabela de pesquisa / matriz hash / associativa a partir do primeiro arquivo e use o conteúdo do segundo arquivo para inseri-lo:

awk -F'[ ,]+' 'NR==FNR {a[$NF] = $2; next} $1 in a {print a[$1], $1}' file1 file2
12347 foo3.bar.com
12348 foo4.bar.com
12345 foo1.bar.com
12349 foo5.bar.com
12346 foo2.bar.com
    
por 19.04.2018 / 01:31
0

Com base no arquivo de exemplo, resposta da steeldriver (usando uma tabela de pesquisa / matriz associativa em awk ) é provavelmente a melhor solução. Embora seja geralmente desaconselhável, você pode fazer a mesma coisa puramente no bash:

declare -A id
while IFS=" ," read x idnum xx name
do
        id[$name]=$idnum
done < file1
while read name
do
        printf '%s %s\n' "${id[$name]}" "$name"
done < file2

A lógica é a mesma:

  1. Um primeiro passo, que cria um array, indexados por valores de nome, contendo valores de ID.
  2. Um segundo passe, que mapeia nomes para IDs e os exibe lado a lado.

Minha resposta funciona conforme desejado (por exemplo, conforme especificado) para os dados de amostra na pergunta. (Desde que usa uma matriz - especificamente, uma matriz associativa - requer bash (ou ksh, zsh ou yash); matrizes não são especificadas pela especificação POSIX para o shell, e não estão disponíveis em todos os shells que são usados no Unix / Linux.) Por causa da maneira como o comando read do bash funciona, minha resposta também lida com nomes de várias palavras (ou seja, nomes com espaços neles) como se poderia esperar intuitivamente:

        file1                             file2                    output

ID: 42, Name: fat cat                   fat cat                  42 fat cat
ID: 95, Name: Superman                  under dog                83 under dog
ID: 83, Name: under dog                 spider man      ⟹       17 spider man
ID:  9, Name: cat woman                 spider pig               60 spider pig
ID: 17, Name: spider man                Superman                 95 Superman
ID: 60, Name: spider pig                cat woman                9 cat woman

Observe que as duas respostas diferenciam maiúsculas e minúsculas; por exemplo, foo1.bar.com não corresponderia a Foo1.bar.com .

    
por 19.04.2018 / 04:47