所以我有一个文件,其中包含有关工资信息的列(例如 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会很好。