두 개의 숫자 목록을 비교하려면 파일 B의 처음 2개 열에 대해 파일 A의 값 범위를 확인해야 합니다.

두 개의 숫자 목록을 비교하려면 파일 B의 처음 2개 열에 대해 파일 A의 값 범위를 확인해야 합니다.

입력 파일:

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하고 각 범위의 시작과 끝을 두 개의 배열 rs(시작용) 및 re(끝용)에 저장합니다. 이러한 배열은 파일의 범위에 할당된 레이블로 색인화됩니다.

두 번째 파일을 구문 분석할 때(두 번째 코드 블록에서 수행됨) 이러한 변수의 각 범위를 반복하고 숫자가 그 중 하나에 속하는지 테스트합니다. 그렇다면 범위의 레이블과 함께 숫자를 출력합니다(코드에서는 레이블이 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첫 번째 줄은 값이 file 사이의 모든 숫자인 배열을 만듭니다 $3.$1$2B.txt

두 번째 줄은 이 배열에서 값을 읽습니다. 그 값은 에 나와 있습니다 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

관련 정보