
Eu tenho uma pergunta bastante específica e consegui encontrar muitos subconjuntos condicionais usando awk, mas nenhum que forneça código explícito suficiente para generalizar para minha situação. Eu tenho um arquivo 'chaves' e um arquivo 'recursos'sem cabeçalhos. A tabela 'chaves' contém duas variáveis, KEY e GROUP (1ª e segunda colunas, respectivamente), exemplo abaixo.
1 GROUP0
2 GROUP0
3 GROUP1
4 GROUP1
5 GROUP2
6 GROUP2
O arquivo 'features' contém uma lista de recursos de widgets como este (ID, FEATURE, VALUE 1ª, 2ª e 3ª colunas, respectivamente).
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
Estou tentando selecionar todas as linhas para um ID que tem um valor de 'KEY' que está na coluna 'KEY' de 'chaves' para uma lista codificada de valores de 'GROUP'. O resultado desejado é
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
Alguma ideia?
Responder1
Aqui está uma abordagem de 3 passagens com o 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
Supondo que o texto acima esteja salvo em selectrows.awk
, use-o assim:
awk -f selectrows.awk keys.txt features.txt features.txt
ou, tudo em uma linha:
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
Responder2
Supondo que você tenha as relações chave/grupo no arquivo keys
e seus recursos no arquivo, features
os resultados abaixo serão esperados de acordo com a entrada fornecida:
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
É apenas uma solução, não necessariamente boa, talvez até a pior em termos de desempenho, mas ainda assim uma.
Responder3
Encontrei esta solução mais curta:
grep -P "^\ +[`awk '$3==""{a[$1]=$2}; $2=="KEY" && $3 in a {printf "%s", $1}' \
<(cat keys features)`]" features
Ele gera um comando parecido com este:
grep -P "^\ +[ABD]" features
... onde a ABD
parte do meio é reunida pela awk
instrução