如果查询列位于两列值之间,则取另一列的值

如果查询列位于两列值之间,则取另一列的值

所以我有一个文件,其中包含有关工资信息的列(例如 2674 美元)-

indi  salary
   sam    2674
   john   6375
   max    9547

另一个文件,其工资范围(第 1 列和第 2 列)位于相应的级别(第 3 列)

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

现在我想根据工资将文件1中的那些人分配到相应的级别

所以最终的输出是

    indi    Rank
     sam    Deputy
     john   Assistant
     max    Manager

如何在 Linux 中使用相同的数据集类型但具有更大的数据来实现此目的?

答案1

假设薪水和薪水界限始终是整数,并且薪水范围不重叠,以下是可能有效的方法(在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

答案2

我不会在大量数据上推荐它,但我想我会尝试 bash 解决方案。我不太bash 流利,但这似乎是处理事情的“明显”方式,“从算法上来说”。这基本上会迭代每个文件并搜索合适的范围。我在评论中给出了一些细节。

该脚本必须这样执行:

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

工资文件包含 Sam、John 和 Max 的工资,而范围包含您的范围和级别(2000 至 4000 为副职,4000 至 6000 为秘书,依此类推)。

#!/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

请注意,我的范围检查包含下限,但不包含上限:

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

如果这不是您期望的行为,您可能需要更改此行。我也尝试尽可能少地打开文件,但由于 bash 不处理文件查找,我仍然需要定期关闭/重新打开范围文件。老实说,如果您要处理非常大的文件,我建议您使用稍低级别的实现。 C会很好。

相关内容