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

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

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

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

예는 다음과 같습니다.

  • ${ListToCheckFrom}임의의 행 > 열 2 및 < 열 3의 숫자인 경우 열 2의 행만 인쇄한다고 가정합니다.${ListToCheckAgainst}

  • 입력 예:

    ListToCheckFrom="C,2  
    C,22  
    C,12  
    hr,15"
    
    ListToCheckAgainst="C1,25,50  
    hr1,22,30  
    r,12,18  
    C,15,44"  
    
  • 예상 출력:

    C,22  
    hr,15
    

답변1

질문에 로 태그를 지정했으므로 bash프로세스 대체를 활용하여 입력 파일과 같은 셸 변수를 읽을 수 있습니다. 다음 스크립트 조각은 다음을 수행해야 합니다.

#!/bin/bash

ListToCheckFrom="C,2  
C,22  
C,12  
hr,15"

ListToCheckAgainst="C1,25,50  
hr1,22,30  
r,12,18  
C,15,44"

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")

이는 echo첫 번째 입력 파일의 내용과 두 번째 입력 파일의 내용을 지정합니다. 현재 처리 중인 "파일"을 내부적으로 구별할 수 있도록 각 파일이 "열려" 있거나 그 전에 변수를 설정합니다.$ListToCheckAgainstecho$ListToCheckFromawklistconstrchkawk

  • 에서 "제약조건"을 처리할 때 $ListToCheckAgainst단순히 열 2와 3에 지정된 "하한"과 "상한"을 각각 배열 low및 에 저장합니다 high. 그렇지 않으면 즉시 다음 입력 라인으로 처리를 건너뜁니다.
  • 확인할 목록을 처리할 때 $ListToCheckFrom이전에 등록된 모든 범위를 검색하고 열 2가 해당 범위 중 하나에 속하는 것을 발견하면 이를 인쇄합니다(그리고 즉시 다음 입력 라인으로 처리를 건너뜁니다).

데이터가 쉘 변수가 아닌 "물리적" 파일에 저장되어 있는 경우 프로세스 대체 대신 파일 이름을 명령줄 인수로 사용할 수 있습니다.

답변2

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

ListToCheckFrom='C,2
C,22
C,12
hr,15'

ListToCheckAgainst='C1,25,50
hr1,22,30
r,12,18
C,15,44'

awk '
    BEGIN { FS="," }
    NR==FNR {
        begs2ends[$2] = $3
        next
    }
    {
        for ( beg in begs2ends ) {
            beg += 0
            end = begs2ends[beg]+0
            if ( (beg < $2) && ($2 < end) ) {
                print
                next
            }
        }
    }
' <(printf '%s\n' "$ListToCheckAgainst") <(printf '%s\n' "$ListToCheckFrom")

$ ./tst.sh
C,22
hr,15

관련 정보