
У меня довольно конкретный вопрос, и я смог найти много информации об условном подмножестве с использованием 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
оператором