2番目のファイルの特定の値に基づいてファイルの行を選択します。

2番目のファイルの特定の値に基づいてファイルの行を選択します。

2つのファイルがあります。

一つは「total.txt」です。ここには2つの列があります。最初の列は1から20までの自然数(指標)で、2番目の列には乱数が含まれています。

1 321
1 423
1 2342
1 7542
2 789
2 809
2 5332
2 6762
2 8976
3 42
3 545
... ...
20 432
20 758

もう一つは「index.txt」です。 4 つの列があります: (1. 指標、2: 低い値、3: 高い値、4: 地域名)

1 400 5000 R1
2 600 800 R2
2 4000 8000 R3
11 300 4000 R4

最初の列が「index.txt」ファイルの最初の列と一致する「total.txt」ファイルの行を出力したいと思います。同時に、出力の2番目の列は「index.txt」の2番目の列より大きく(>)、「index.txt」の3番目の列より小さくなければなりません(<)。そして必ず地域名を一緒に記載しなければなりません。

予想される結果は次のとおりです。

1 423 R1
1 2342 R1
2 809 R2
2 5332 R3
2 6762 R3
11 ... R4
11 ... R4

私はこれを試しました:

awk 'FNR == NR { low[$1]=$2; high[$1]=$3; reg[$1]=$4; next} 
     $2 >= low[$1] && $2 <= high[$1] {print $0,reg[$1]}' index.txt total.txt > result.txt

結果は次のとおりです(R2領域がありません)。

1 423 R1
1 2342 R1
2 5332 R3
2 6762 R3
11 ... R4
11 ... R4

私に説明し、対処方法を教えてもらえますか?ありがとうございます!

実際に結果が異なる領域に応じて出力される場合は、より良いでしょう。つまり、この例では、異なる領域(R1.txt、R2.txt、R3.txt、およびR4)を含む4つのテキストファイルを作成するのが最善です。 .txt).ありがとうございます!

答え1

両方の入力ファイル(最初の列)のインジケータは一意ではないため、キーとして使用するのは困難です。ただし、ゾーンIDが一意の場合は、次のものを使用できます。

 $ awk 'FNR == NR { reg=$4; low[reg]=$2; high[reg]=$3; ind[reg]=$1; next} 
  { for (reg in ind) { 
      if ($1 == ind[reg] && $2 >= low[reg] && $2 <= high[reg]) {
         print $0,reg
      } } }' index.txt total.txt
1 423 R1
1 2342 R1
2 789 R2
2 5332 R3
2 6762 R3

これはデフォルトで領域をインジケータにマップし、2番目のファイルのどの行が一致するかを確認するためにforループを追加したコードです。

2 789 R2(vsの場合、2 809 R2制限が600と800の場合、なぜ809を印刷するのかわかりません。)

print $0,reg > reg ".txt"ゾーンごとに名前付きファイルに出力するように印刷コマンドを変更します。

関連情報