クエリ列が2つの列の値の間にある場合は、他の列の値を取得します。

クエリ列が2つの列の値の間にある場合は、他の列の値を取得します。

そのため、給与情報(例:$ 2674)の列を含むファイルがあります。

indi  salary
   sam    2674
   john   6375
   max    9547

そのレベル(3列)の給与範囲(1列と2列)を含む別のファイル

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ソリューションを試してみるかと思いました。私はあまりそうではありません。流暢なバッシュしかし、これは「アルゴリズム的に言えば」仕事を処理する「明らかな」方法のようです。これはデフォルトで各ファイルを繰り返し、適切な範囲を検索します。コメントにいくつかの詳細をお知らせしました。

スクリプトは次のように実行する必要があります。

$ ./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は大丈夫でしょう。

関連情報