そのため、給与情報(例:$ 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は大丈夫でしょう。