awk를 사용하여 한 변수의 특정 열 집합에 있는 각 행에 대한 정보를 다른 변수의 세 가지 특정 열에 있는 모든 행에 대해 확인합니다.

awk를 사용하여 한 변수의 특정 열 집합에 있는 각 행에 대한 정보를 다른 변수의 세 가지 특정 열에 있는 모든 행에 대해 확인합니다.

오늘 이전에도 아주 비슷한 질문을 했는데, 명령의 매개변수를 늘려야 한다는 것을 깨달았습니다. 다른 매개변수를 사용하여 명령을 편집했는데 다음 매개변수를 사용하면 성공률이 낮아지는데 이유를 모르겠습니다. 이것이 제가 해결하려고 노력하고 있는(그리고 실패하고 있는) 문제입니다.

awk한 변수에 있는 특정 열 집합의 각 행에 있는 정보를 다른 변수에 있는 두 개의 특정 열에 있는 모든 행에 대해 확인 하고 매개 변수와 일치하는 첫 번째 변수에 행을 유지하는 데 사용해야 합니다 .

지금까지 나는 강력한 명령을 통해 awk이 작업을 수행하려고 시도했지만 실패했습니다. 분명히 외부 루프에서 이 작업을 수행할 수 있지만 확인할 행이 수백 또는 수천 개 있으므로 매우 느릴 것입니다. 이 문제에 대해 도움을 주시면 감사하겠습니다. 저는 항상 awk 사용을 개선하기 위해 노력하고 있습니다. 따라서 해결책이 있다면 제가 배우고 개선할 수 있도록 설명이 있으면 좋을 것입니다.

예는 다음과 같습니다.

  • ${ListToCheckFrom}열 2 >= 및 열 3 <= 행의 해당 열인 경우 에만 행을 인쇄한다고 가정합니다 ${ListToCheckAgainst}. 또한 의 열 1은 ${ListToCheckFrom}다음의 열 1과 동일해야 합니다.${ListToCheckAgainst}

  • 입력 예:

ListToCheckFrom="r,2,3
C,22,24
C,12,13
C,51,59
C,15,20
C,13,18"
        
ListToCheckAgainst="C,25,50
C,22,30
C,12,18
C,15,17
C,1,12
C,60,200"

  • 예상 출력:
C,22,24  
C,12,13
C,15,20
C,13,18
  • 제가 시도한 것은 오늘 제가 물은 더 간단한 질문에 대한 답변을 바탕으로 한 것입니다(@AdminBee에게 감사드립니다).
awk -F',' 'list=="constraints"{n++; low[n]=$2;high[n]=$3;c[n]=$1;next}
           {for (i=1;i<=n;i++) {if (($1==c[i])&&($2>=low[i]&&$2<=high[i])||($3>=low[i]&&$3<=high[i])) {print;next};}}' list=constraints <(echo "$ListToCheckAgainst") list=check <(echo "$ListToCheckFrom")

저는 우분투를 사용하고 있습니다.

답변1

확립된또 다른 대답이전 질문으로 돌아왔습니다.

$ cat tst.sh
#!/usr/bin/env bash

ListToCheckFrom="r,2,3
C,22,24
C,12,13
C,51,59
C,15,20
C,13,18"

ListToCheckAgainst="C,25,50
C,22,30
C,12,18
C,15,17
C,1,12
C,60,200"

awk '
    BEGIN { FS="," }
    NR==FNR {
        vals[NR] = $0
        next
    }
    {
        for ( nr in vals ) {
            split(vals[nr],v)
            if ( (v[1] == $1) && ( (v[2] <= $2) && ($2 <= v[3]) ) ) {
                print
                next
            }
        }
    }
' <(printf '%s\n' "$ListToCheckAgainst") <(printf '%s\n' "$ListToCheckFrom")

$ ./tst.sh
C,22,24
C,12,13
C,15,20
C,13,18

수정에 관해 문의하신 스크립트와 관련하여 이전 질문에 대한 답변은 다음과 같습니다.

awk -F',' 'list=="constr"{n++; low[n]=$2;high[n]=$3;next}
           {for (i=1;i<=n;i++) {if ($2>low[i]&&$2<high[i]) {print;next};}}' \
           list=constr <(echo "$ListToCheckAgainst") \
           list=chk <(echo "$ListToCheckFrom")

이를 향상시키려는 첫 번째 단계는 읽기 쉽게 만드는 것입니다. 예를 들어 awk 부분을 실행 gawk -o-하고 그 주위에 쉘 부분을 다시 추가하면 다음과 같은 결과를 얻을 수 있습니다.

awk -F',' '
    list == "constr" {
            n++
            low[n] = $2
            high[n] = $3
            next
    }
    
    {
            for (i = 1; i <= n; i++) {
                    if ($2 > low[i] && $2 < high[i]) {
                            print
                            next
                    }
            }
    }
' \
list=constr <(echo "$ListToCheckAgainst") \
list=chk <(echo "$ListToCheckFrom")

새로운 요구 사항을 충족하려면 다음과 같이 변경하기만 하면 된다는 것을 쉽게 알 수 있기를 바랍니다.

awk -F',' '
    list == "constr" {
            n++
            key[n] = $1
            low[n] = $2
            high[n] = $3
            next
    }
    
    {
            for (i = 1; i <= n; i++) {
                    if ( (key[i] == $1) && ($2 > low[i] && $2 < high[i]) ) {
                            print
                            next
                    }
            }
    }
' \
list=constr <(echo "$ListToCheckAgainst") \
list=chk <(echo "$ListToCheckFrom")

관련 정보