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

관련 정보