awk
Útiles de una sola línea: cálculo del promedio de un CSV, etc.
Buscar..
Procesamiento robusto de datos tabulares (CSV et al.)
El procesamiento de datos tabulares con awk es muy fácil, siempre que la entrada tenga el formato correcto. La mayoría de los programas que producen datos tabulares utilizan características específicas de esta familia de formatos, y los programas awk que procesan datos tabulares suelen ser específicos de los datos producidos por un software específico. Si se requiere una solución más genérica o robusta, los idiomas más populares proporcionan bibliotecas que se adaptan a muchas características que se encuentran en los datos tabulares:
- Nombres de columna opcionales en la primera línea
- Mezcla de valores de columna entre comillas y no entre comillas.
- varios delimitadores
- Formatos localizados para números flotantes.
Si bien definitivamente es posible manejar todas estas funciones de forma limpia y genérica con awk, probablemente no valga la pena.
Intercambio de dos columnas en datos tabulares.
Dado un archivo usando ; como delimitador de columna. Permutando la primera y la segunda columna se logra mediante
awk -F';' -v 'OFS=;' '{ swap = $2; $2 = $1; $1 = swap; print }'
Calcular el promedio de los valores en una columna a partir de datos tabulares
Dado un archivo usando ; como delimitador de columna. Calculamos la media de los valores en la segunda columna con el siguiente programa, la entrada proporcionada es la lista de calificaciones de un grupo de estudiantes:
awk -F';' '{ sum += $2 } END { print(sum / NR) }' <<EOF
Alice;2
Victor;1
Barbara;1
Casper;4
Deborah;0
Ernest;1
Fabiola;4
Giuseppe;4
EOF
La salida de este programa es 2.125 .
Recuerde que NR contiene el número de la línea que se está procesando, en el bloque END , por lo tanto, mantiene el número total de líneas en el archivo.
Recuerde que en muchas aplicaciones (monitoreo, estadísticas) , la mediana es una información mucho más útil. Vea el ejemplo correspondiente.
Selección de columnas específicas en datos tabulares
Asumimos un archivo usando; como delimitador de columna. La selección de un conjunto específico de columnas solo requiere una declaración de impresión . Por ejemplo, el siguiente programa selecciona las columnas 3, 4 y 7 de su entrada:
awk -F';' -v 'OFS=;' '{ print $3, $4, $7 }'
Es posible, como siempre, elegir más cuidadosamente las líneas para imprimir. El siguiente programa selecciona las columnas 3, 4 y 7 de su entrada cuando el primer campo es Alice o Bob :
awk -F';' -v 'OFS=;' '($1 == "Alice") || ($1 == "Bob") { print $3, $4, $7 }'
Calcular la mediana de valores en una columna a partir de datos tabulares
Dado un archivo usando ; como delimitador de columna. Calculamos la mediana de los valores en la segunda columna con el siguiente programa, escrito para awk de GNU . La entrada proporcionada es la lista de calificaciones de un grupo de estudiantes:
gawk -F';' '{ sample[NR] = $2 }
END {
asort(sample);
if(NR % 2 == 1) {
print(sample[int(NR/2) + 1])
} else {
print(sample[NR/2])
}
}' <<EOF
Alice;2
Victor;1
Barbara;1
Casper;4
Deborah;0
Ernest;1
Fabiola;4
Giuseppe;4
EOF
La salida de este programa es 1 .
Recuerde que NR contiene el número de la línea que se está procesando, en el bloque END , por lo tanto, mantiene el número total de líneas en el archivo.
Muchas implementaciones de awk no tienen una función para ordenar matrices, por lo que es necesario definirlas antes de poder utilizar el código anterior.
Seleccionando un conjunto de líneas entre dos patrones.
La comparación de patrones se puede utilizar de manera efectiva con awk ya que controla las acciones que lo siguen, es decir, { pattern } { action } . Un buen uso de la coincidencia de patrones es seleccionar múltiples entre dos patrones en un archivo, por ejemplo, patternA y patternB
$ awk '/patternA/,/patternB/' file
Supongamos que el contenido de mi archivo es el siguiente, y quiero extraer las líneas solo entre el patrón anterior:
$ cat file
This is line - 1
This is line - 2
patternA
This is line - 3
This is line - 4
This is line - 5
patternB
This is line - 6
$ awk '/patternA/,/patternB/' file
patternA
This is line - 3
This is line - 4
This is line - 5
patternB
El comando anterior no realiza ninguna { action } específica más que para imprimir las líneas coincidentes, pero cualquier acción específica dentro del subconjunto de líneas se puede aplicar con un bloque de acción ( {} ).