
入力ファイル:
A.txt
含む:
111
222
223
344
100002
99991
B.txt
含む:
100 199 A
200 299 B
300 399 C
400 499 D
私はこの出力が欲しい
111 A
222 B
223 B
344 C
答え1
B.txt
で定義した範囲内の値A.txt
とその範囲のラベルを出力しようとしています。
$ awk 'FNR==NR { rs[$3] = $1; re[$3] = $2; next } { for (s in rs) if ($1 >= rs[s] && $1 <= re[s]) { print $1, s; next } }' A.txt B.txt
111 A
222 B
223 B
344 C
最初のブロックは範囲を解析し、A.txt
各範囲の開始と終了を2つの配列rs
(開始)とre
(終了)に格納します。これらの配列は、ファイルの範囲に割り当てられたラベルでインデックス付けされます。
2番目のファイルを解析するとき(2番目のコードブロックで実行されます)、これらの変数の各範囲を繰り返し、数字がその1つに属するかどうかをテストします。そうであれば、範囲内のラベルと共に数字を出力します(コードではラベルはs
「文字列」として抽出されます)。
上記のコードと上記のコードの主な違いpLumoが提供するコード私のコードは与えられた各入力数の範囲を繰り返すことによってその数を含む範囲を見つけますが、コードはルックアップを高速化するために各範囲の各整数を格納します。彼らのコードは小さな範囲で多くのクエリを実行するのに使いやすいですが、私のコードはメモリ効率を向上させるためにスピードを交換し、範囲が大きいか少ないクエリを実行する必要がある場合に好まれます。
答え2
以下を試してくださいawk
。
awk '
FNR==NR{for(n=$1;n<=$2;n++)v[n]=$3}
FNR!=NR{if(v[$1])print $1,v[$1]}
' B.txt A.txt
v
最初の行は、値がファイルの間のすべての数値である配列を作成します$3
。$1
$2
B.txt
2行目はこの配列から値を読み取ります。その値はに示されていますA.txt
。
出力:
111 A
222 B
223 B
344 C
答え3
awk -v test="$(awk '{print $1+0}' A.txt)" '{ if ($1 > test && $2 < test) {print test,$3} }' B.txt