Bash:数値範囲を一致させて行をフィルタリング

Bash:数値範囲を一致させて行をフィルタリング

ファイルがあります。テストフィールドを含める:加藤場所

1   7100
1   35000
1   49321
1   49759
2   44842
2   52794
2   53558
3   53859
3   54013
3   55172

ファイルがあります。フィールドを含める:加藤スタートそして止める

1   6408    8000
1   11822   16373
1   18716   23389
1   27690   34330
1   36552   39191
1   39313   44565
2   44839   50247
2   60987   65017
2   65705   71523

私の目標は、ファイルから行を選択することですposファイルのwhereフィールドテスト範囲内に属するスタートそして止める記録したもの。指定された時間内にゲームをプレイする必要があるという制限があります。加藤グループ。どちらのファイルもフィールド 1 と 2 に基づいてソートされます。ちなみに、私の2つの実際のファイルには他の多くのフィールドがあります。

このサンプル・データ・セットの予想結果は次のとおりです。

1   6408    8000
2   44839   50247

私が混ぜ合わせたスクリプトがあります。

k=1;
data_test=$(cat "test")
data_db=$(cat "db")
while read -r line
do
  # helps to keep count of test rows
  printf "$k \n"

  # get cato
  cato=$(echo $line | awk '{print $1}')
  # get pos
  pos=$(echo $line | awk '{print $2}')
  # get number of chars in pos (to reduce number of lines awk needs to look through later)
  pos_chr=$(echo -n $pos | wc -c)
  # get lines in db that start with cato and pos chars match start or stop
  matched=$(echo "$data_db" | grep -Ew "^$cato" | grep -Ew "[0-9]{$pos_chr}")
  #echo "$db_cat"

  # if matched is not empty
  if [ ! -z "$matched" ]; then
    # use awk to print lines in db where pos > start and pos < stop
    echo "$matched" | awk -v apos='$pos' 'BEGIN{OFS="\t"}{if(apos >= $2 && apos <= $3) print $0}'
    #check
    #echo "$matched" | awk -v apos=$pos 'BEGIN{OFS="\t"}{print apos,$0}'
  fi

  ((k=k+1))
done <<< "$data_test"

awk最後の段階で比較が行われていないようです。すべてが最後の段階まで行われているようですが、何が起こっているのかわかりません。誰かがエラーを見たかもしれません。もっと良い方法がありますか?

ベストアンサー1

単一のGNUを使用するawkプログラム(Gawkv4.0以降):

awk 'NR==FNR{ a[$1][$2]; next }
     $1 in a{ 
         for (i in a[$1]) 
             if (i >= $2 && i <= $3) { print $0; break }
     }' test db

出力:

1   6408    8000
2   44839   50247

おすすめ記事