Pegue o valor de outra coluna se a coluna de consulta estiver entre dois valores de coluna

0

Então eu tenho um arquivo com coluna que tem informações sobre salário (por exemplo, 2674 dólares) -

indi  salary
   sam    2674
   john   6375
   max    9547

e outro arquivo com a escala do salário (column1 & colum2) em sua classificação correspondente (column3)

salary_min salary_max Rank
2000           4000    Deputy
4000           6000    secretary
6000           8000    Assistant
8000           10000   Manager

Agora, gostaria de atribuir esses indivíduos do arquivo 1 com base no salário à classificação correspondente

para que o resultado final seja

    indi    Rank
     sam    Deputy
     john   Assistant
     max    Manager

Como posso conseguir isso no Linux no mesmo tipo de conjunto de dados, mas com dados maiores?

    
por I Phoenix 15.12.2014 / 13:23

2 respostas

1

Supondo que os salários e os limites salariais serão sempre números inteiros e que os intervalos salariais não se sobrepõem, aqui está algo que pode funcionar (em bash )

{ printf "indi Rank\n" ; 
join -o1.1,2.2 <(tail -n +2 file1 | sort -b -k2,2) -1 2 -2 1 \
<(awk 'FNR > 1{for (i=$1; i<$2; ++i) printf "%d %s\n", i, $3}' file2 | sort -k1,1) ;}
indi Rank
sam Deputy
john Assistant
max Manager
    
por 15.12.2014 / 14:57
0

Eu não recomendaria isso em uma grande quantidade de dados, mas pensei em testar uma solução bash. Eu não sou muito bash-fluent , mas isso parece ser a maneira "óbvia" de lidar com as coisas, "falando em algoritmos". Isso basicamente itera sobre cada arquivo e procura o bom intervalo. Eu dei alguns detalhes nos comentários.

O script deve ser executado desta forma:

$ ./script.sh [salaries] [ranges]

O arquivo salaries contém os salários de Sam, John e Max, enquanto intervalos contém seus ranges e ranks (2000 a 4000 é vice, 4000 a 6000 é secretário, e assim em).

#!/bin/bash

test $# -ne 2 && exit 1
test ! -r "$1" -o ! -r "$2" && exit 2

# Open the salary file (3) and the ranges (4).
exec 3< "$1"
exec 4< "$2"

# Echo the salary headers.
read -d$'\n' headers <&3
echo "$headers" | tr -s ' '

# For each line in the salary file...
while read name salary; do
    # Skip the ranges headers ("salary_min...").
    read -d$'\n' skip <&4

    # For each range...
    while read min max rankname; do
    # If the salary is within the range, print name and rank.
    if [ "$salary" -ge $min -a "$salary" -lt $max ]; then
        echo "$name $rankname"
    fi
    done <&4

    # Reopen the range file for the next employee.
    exec 4>&-
    exec 4< "$2"
done <&3

exit 0

Observe que minhas verificações de intervalos são inclusivas no limite inferior, mas exclusivas no superior:

[ "$salary" -ge $min -a "$salary" -lt $max ]

Você pode querer mudar esta linha se não for o comportamento esperado. Eu também tentei abrir arquivos o mais raramente possível, mas como o bash não lida com busca de arquivos , eu ainda preciso fechar / reabrir o arquivo de intervalos regularmente. Para ser honesto, eu recomendaria uma implementação de nível um pouco menor, se você for lidar com arquivos muito grandes. C seria legal.

    
por 15.12.2014 / 15:10