es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

awk: calcular los valores promedio para los datos en archivos diferentes

Estoy usando bash + awk para extraer información de archivos de registro ubicados dentro del directorio y guardar el resumen en un archivo separado.
En la parte inferior de cada archivo de registro, hay una tabla como la siguiente:

modo  | afinidad  | distancia desde el mejor modo
      | (kcal/mol)| rmsd l.b.| rmsd u.b.
-----+------------+----------+----------
   1      -6.961         0         0
   2      -6.797      2.908     4.673
   3      -6.639      27.93     30.19
   4      -6.204      2.949     6.422
   5      -6.111      24.92     28.55
   6      -6.058      2.836     7.608
   7      -5.986      6.448     10.53
   8      -5.95        19.32     23.99
   9      -5.927      27.63     30.04
  10     -5.916      27.17     31.29
  11     -5.895      25.88     30.23
  12     -5.835      26.24     30.36

A partir de esto, necesito centrarme en los valores (negativos) ubicados en la segunda columna. Específicamente, necesito tomar los primeros 10 valores de la segunda columna (desde -6.961 hasta -5.916) y calcular la media y guardar el valor de la media junto con el nombre del registro como una cadena en el archivo nuevo ranking.log.
Así que para 5 registros procesados debería ser algo como esto:

# ranking_${output}.log
nombre_log1 -X.XXX
nombre_log2 -X.XXX
nombre_log3 -X.XXX
nombre_log4 -X.XXX
nombre_log5 -X.XXX

Donde -X.XXX es el valor medio calculado para cada registro en las primeras 10 posiciones.

Aquí está mi código awk integrado en una función bash, que extrae el primer valor (-6.961 en el ejemplo de la tabla) de cada registro (sin el cálculo de la media).

# tomar solo la primera línea (dG más bajo) de cada registro
take_the_first_value () {
    awk '$1=="1"{sub(/.*\//,"",FILENAME); sub(/\.log/,"",FILENAME); printf("%s: %s\n", FILENAME, $2)}' "${results}"/*.log  > "${results}/ranking.csv"
} 

¿Puedo modificar la parte de AWK para agregar el cálculo de los valores de la media en lugar de tomar siempre el valor ubicado en la primera línea de la tabla?

Tags:  

Answer

  1. Avatar for davy.ai

    Sí, puedes modificar la parte de AWK para calcular los valores promedio en lugar de tomar solo el primer valor. Aquí tienes un código AWK actualizado que debería hacer lo que necesitas:

    # calcular el promedio de los primeros 10 valores negativos en cada registro
    calcular_valores_promedio () {
        for log_file in "${results}"/*.log; do
            log_name=$(basename "$log_file" .log)
            mean_value=$(awk '
                # coincidir las líneas con valores negativos en la segunda columna
                $2 ~ /^-/ {
                    # incrementar el contador de valores negativos
                    count++
                    # agregar el valor negativo a la suma
                    sum += $2
                    # detener el procesamiento si hemos alcanzado 10 valores negativos
                    if (count == 10) {
                        # calcular el promedio e imprimirlo junto con el nombre del registro
                        printf("%s %s\n", FILENAME, sum/10)
                        exit
                    }
                }
            ' "$log_file")
            # escribir el nombre del registro y el valor promedio en el archivo de clasificación
            printf "%s %s\n" "$log_name" "$mean_value"
        done > "${results}/ranking.log"
    }
    

    Este código recorre cada archivo de registro y utiliza AWK para coincidir las líneas con valores negativos en la segunda columna. Incrementa un contador del número de valores negativos vistos y los agrega a una suma. Una vez que ha visto 10 valores negativos, calcula el promedio e imprime el resultado junto con el nombre del registro. Luego, los resultados se escriben en el archivo ranking.log.

Comments are closed.