
Tengo una pregunta bastante específica y he podido encontrar muchos subconjuntos condicionales usando awk, pero ninguno que me brinde suficiente código explícito para generalizar mi situación. Tengo un archivo 'claves' y un archivo 'características' ambossin encabezados. La tabla 'claves' contiene dos variables, CLAVE y GRUPO (primera y segunda columnas, respectivamente), como se muestra a continuación.
1 GROUP0
2 GROUP0
3 GROUP1
4 GROUP1
5 GROUP2
6 GROUP2
El archivo 'características' contiene una lista de características de widgets como este (ID, CARACTERÍSTICA, VALOR 1.ª, 2.ª y 3.ª columnas, 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
Estoy intentando seleccionar todas las filas para una ID que tiene un valor de 'CLAVE' que se encuentra en la columna 'CLAVE' de 'claves' para obtener una lista codificada de valores de 'GRUPO'. El resultado deseado es
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
¿Algunas ideas?
Respuesta1
Aquí hay un enfoque de 3 pasos con 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
Suponiendo que lo anterior esté guardado en selectrows.awk
, utilícelo así:
awk -f selectrows.awk keys.txt features.txt features.txt
o, todo en una línea:
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
Respuesta2
Suponiendo que tiene las relaciones clave/grupo en el archivo keys
y sus características en el archivo, features
a continuación se obtienen los resultados esperados según la entrada que proporcionó:
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
Es solo una solución, no necesariamente buena, tal vez incluso la peor en cuanto a rendimiento, pero sigue siendo una.
Respuesta3
Encontré esta solución más corta:
grep -P "^\ +[`awk '$3==""{a[$1]=$2}; $2=="KEY" && $3 in a {printf "%s", $1}' \
<(cat keys features)`]" features
Genera un comando que se ve así:
grep -P "^\ +[ABD]" features
...donde la ABD
parte -en el medio está reunida por la awk
declaración