AWK: 헤더가 없는 중첩된 조건부 행 하위 집합

AWK: 헤더가 없는 중첩된 조건부 행 하위 집합

나는 매우 특정한 문제를 안고 있으며 awk를 사용하여 하위 집합 조건에 대해 많은 것을 찾을 수 있었지만 그 중 어느 것도 내 상황에 일반화할 수 있을 만큼 명확한 코드를 제공하지 않았습니다. "keys" 파일과 "features" 파일이 있습니다.제목 없음. "keys" 테이블에는 아래와 같이 KEY와 GROUP(각각 첫 번째 열과 두 번째 열)이라는 두 개의 변수가 포함되어 있습니다.

    1          GROUP0
    2          GROUP0
    3          GROUP1
    4          GROUP1
    5          GROUP2
    6          GROUP2  

"features" 파일에는 이와 같은 위젯의 기능 목록이 포함되어 있습니다(각각 ID, FEATURE, VALUE 첫 번째, 두 번째 및 세 번째 열).

    A           num_user     10
    A           KEY          4
    B           num_user     2
    B           KEY          2
    B           battery      Large
    C           num_user     10
    C           KEY          15
    D           num_user     2
    D           KEY          2
    D           battery      Small
    E           num_user     2
    E           KEY          7
    E           battery      Small

하드코드된 "GROUP" 값 목록에 대해 "keys"의 "KEY" 열에 "KEY" 값이 있는 ID를 가진 모든 행을 선택하려고 합니다. 원하는 결과는 다음과 같습니다.

    A           num_user     10
    A           KEY          4
    B           num_user     2
    B           KEY          2
    B           battery      Large
    D           num_user     2
    D           KEY          2
    D           battery      Small

어떤 아이디어가 있나요?

답변1

이것은 awk의 3단계 방법입니다.

FNR == 1 {
        fn++        # counter for File Number, starts at 1
}

fn == 1 {
        key[$1] = 1 # first file: store keys
}

fn == 2 && $2 == "KEY" && $3 in key {
        id[$1] = 1  # second file, first pass: store id's
}

fn == 3 && $1 in id # second file, 2nd pass: print rows

위의 내용이 에 저장되어 있다고 가정하고 selectrows.awk다음과 같이 사용하십시오.

awk -f selectrows.awk keys.txt features.txt features.txt

또는 한 줄에 모두 작성하세요.

awk 'FNR == 1 {f++}; f == 1 {k[$1]}; f == 2 && $2=="KEY" && $3 in k {i[$1]}; f == 3 && $1 in i' keys.txt features.txt features.txt

답변2

파일에 키/그룹 관계가 있고 keys파일에 함수가 있다고 가정하면 features다음은 제공한 입력을 기반으로 예상되는 결과를 제공합니다.

awk '{print $2}' keys | sort -u | xargs -i_group awk '{if($2=="_group")print $1}' keys | sort -u | xargs -i_key awk '{if ($3=="_key" && $2=="KEY")print $1}' features | sort -u | xargs -i_id awk '{if($1=="_id")print $0}' features

이는 단지 솔루션일 뿐이며 반드시 좋은 솔루션은 아니며 성능이 가장 좋지 않을 수도 있지만 그럼에도 불구하고 솔루션입니다.

답변3

이 더 짧은 솔루션을 찾았습니다.

grep -P "^\ +[`awk '$3==""{a[$1]=$2}; $2=="KEY" && $3 in a {printf "%s", $1}' \
<(cat keys features)`]" features

다음과 같은 명령을 생성합니다.

grep -P "^\ +[ABD]" features

... ABD중간 부분은 awk명령문으로 수집됩니다.

관련 정보