sort Arquivo B baseado na coluna 3 do Arquivo A sem alterar o conteúdo do Arquivo A

1

Eu tenho o seguinte arquivo:

cat fileA.txt

seattle    1991  west
atlanta    1993  west
turlock    1998  west
marysville 2004  south
newyork    2007  north
canada     2004  west

E o segundo arquivo é assim:

cat fileB.txt

popular
someWhatPopular
boring
popular
popular
popular

Gostaria de obter a seguinte saída em fileB.txt :

popular popular popular someWhatPopular boring popular

Então, basicamente, estou tentando classificar fileB.txt para fileA.txt terceira coluna

Eu tentei o seguinte código:

   #!/bin/bash
   sort -s -k3,3 fileA.txt fileB.txt

Mas não funcionou. Alguma sugestão? Estou bem aberto para qualquer coisa que não exija codificação. Bash / awk / sed, etc.

    
por oddRas 28.11.2017 / 01:38

3 respostas

1

Este é um problema de estrutura de dados mais do que um linux. Você precisa de uma entrada comum (chave) em ambas as tabelas para vinculá-las, o mesmo que em qualquer 'banco de dados' e é uma boa prática manter uma chave exclusiva na primeira coluna de qualquer tabela de dados. Então você pode classificar e vincular ao conteúdo do seu coração.

Tomando algo como o mapeamento @glennjackman, você define a chave de mapeamento como sendo norte, sul etc.

1 south somewhatPopular
2 west popular
3 north boring
4 east unexplored

em um arquivo chamado arquivo popularity . Alterar fileA para incluir uma chave exclusiva

1 seattle    1991  west
2 atlanta    1993  west
3 turlock    1998  west
4 marysville 2004  south
5 newyork    2007  north
6 canada     2004  west

você pode manipular esses arquivos copiando-os% em sua chave selecionada (na sua coluna de caso 2 em join mapas para a coluna 4 em popularity ), mas fileA precisa que ambos os arquivos sejam classificados na keyfield, então

join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity) | sort -k2 | awk '{print $6}'

popular
popular
popular
somewhatPopular
boring
popular

Um pouco de abordagem de marreta, mas lhe dá mais flexibilidade.

Quebre o comando acima em cada tubo e você verá o que cada etapa faz.

Editar: Explicação de join

Isso diz a join -1 4 -2 2 # its in the man pages para ver a quarta coluna na tabela 1 (-1 4) e encontrar valores correspondentes na segunda coluna da tabela 2 (-2 2).

join compõe colunas das duas tabelas em uma única tabela, mas inclui apenas a coluna-chave (norte etc.) uma vez. Olhe para a saída de

join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity)

e deve ficar mais claro

Como tivemos que classificar as tabelas de dados para que o join funcione, então

| sort -k2

a tabela combinada para colocá-los de volta em sua ordem original.

A coluna que você quer é a coluna 6 na tabela combinada, então apenas

| awk '{print $6}'

para stdout.

    
por 28.11.2017 / 06:45
0

Você pode tentar paste os dois arquivos "table" juntos, enviar a saída para sort e, em seguida, cut para reter apenas a quarta coluna.

Tentativa não testada (celular agora) seria algo como

paste fileA fileB | sort -s -k3,3 | cut -f4

    
por 28.11.2017 / 05:43
0

Você pode obter o mapeamento alfabético com

paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)
north   boring
south   popular
west    someWhatPopular

E então uma forma de sua saída desejada pode ser produzida com o awk:

awk '
    NR==FNR {map[$1] = $2; next} 
    {print map[$NF]}
' <(paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)) fileA.txt
someWhatPopular
someWhatPopular
someWhatPopular
popular
boring
someWhatPopular
    
por 28.11.2017 / 14:32