AWK: Вложенное условное подмножество строк без заголовков

AWK: Вложенное условное подмножество строк без заголовков

У меня довольно конкретный вопрос, и я смог найти много информации об условном подмножестве с использованием awk, но ни одна из них не предоставляет достаточно явного кода для обобщения моей ситуации. У меня есть файл «keys» и файл «features»без заголовковТаблица «ключи» содержит две переменные, KEY и GROUP (первый и второй столбцы соответственно), игрушечный пример ниже.

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

Файл «features» содержит список функций виджетов, таких как (ID, FEATURE, VALUE 1-й, 2-й и 3-й столбцы соответственно).

    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

Я пытаюсь выбрать все строки для идентификатора, который имеет значение 'KEY', которое находится в столбце 'KEY' 'keys' для жестко закодированного списка значений 'GROUP'. Желаемый результат:

    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:

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оператором

Связанный контент