AWK: Subconjunto condicional anidado de filas sin encabezados

AWK: Subconjunto condicional anidado de filas sin encabezados

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 keysy sus características en el archivo, featuresa 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 ABDparte -en el medio está reunida por la awkdeclaración

información relacionada