Pregunta

Creo que AWK es realmente útil. Aquí hay un forro que preparé para manipular datos.

ls | awk '{ print "awk " "'"'"'"  " {print $1,$2,$3} " "'"'"'"  " " $1 ".old_ext > " $1    ".new_ext"  }' > file.csh

Utilicé este AWK para crear un archivo de script que cambiaría el nombre de algunos archivos y solo imprimiría columnas selectivas. Alguien sabe una mejor manera de hacer esto? ¿Cuáles son tus mejores forros AWK one o manipulaciones inteligentes?

¿Fue útil?

Solución

El libro AWK está lleno de excelentes ejemplos. Se solían recopilar para descargar desde página web de Kernighan (404s ahora).

Otros consejos

Puede encontrar varios liners liners aquí .

Yo uso esto:

df -m | awk '{p+=$3}; END {print p}'

Para totalizar todo el espacio en disco utilizado en un sistema a través de sistemas de archivos.

Hace muchos años escribí un script de cola en awk:

#!/usr/bin/awk -f
BEGIN {
  lines=10
}

{
  high = NR % lines + 1
  a[high] = <*>
}

END {
  for (i = 0; i < lines; i++) {
    n = (i + high) % lines + 1
    if (n in a) {
      print a[n]
    }
  }
}

Es una tontería, lo sé, pero eso es lo que te hace awk. Es muy divertido jugar con él.

Henry Spencer escribió una implementación bastante buena de nroff en awk. Lo llamó "awf". También afirmó que si Larry Wall hubiera sabido lo poderoso que era awk, no habría necesitado inventar Perl.

Aquí hay un par de awks que solía usar regularmente ... tenga en cuenta que puede usar $ 1, $ 2, etc. para obtener la columna que desee. Entonces, para manipular un montón de archivos, por ejemplo, aquí hay un comando estúpido que podría usar en lugar de mv ...

ls -1 *.mp3 | awk '{printf("mv %s newDir/%s\n",$1,$1)}' | /bin/sh

O si estás viendo un conjunto de procesos tal vez ...

ps -ef | grep -v username | awk '{printf("kill -9 %s\n",$2)}' | /bin/sh

Bastante trivial, pero puedes ver cómo eso te llevaría de muchas maneras. =) La mayoría de las cosas que solía hacer pueden usar xargs para, pero oye, ¿quién necesita nuevos comandos fallidos?

Utilizo mucho este script para editar PATH y variables de entorno similares a rutas. Uso:

export PATH=$(clnpath /new/bin:/other/bin:$PATH /old/bin:/other/old/bin)

Este comando agrega / new / bin y / other / bin delante de PATH, elimina tanto / old / bin como / other / old / bin de PATH (si está presente, no hay error si está ausente) y elimina entradas de directorio duplicadas en el camino.

:   "@(#)$Id: clnpath.sh,v 1.6 1999/06/08 23:34:07 jleffler Exp <*>quot;
#
#   Print minimal version of $PATH, possibly removing some items

case $# in
0)  chop=""; path=${PATH:?};;
1)  chop=""; path=$1;;
2)  chop=$2; path=$1;;
*)  echo "Usage: `basename <*> .sh` [$PATH [remove:list]]" >&2
    exit 1;;
esac

# Beware of the quotes in the assignment to chop!
echo "$path" |
${AWK:-awk} -F: '#
BEGIN       {       # Sort out which path components to omit
                    chop="'"$chop"'";
                    if (chop != "") nr = split(chop, remove); else nr = 0;
                    for (i = 1; i <= nr; i++)
                            omit[remove[i]] = 1;
            }
{
    for (i = 1; i <= NF; i++)
    {
            x=$i;
            if (x == "") x = ".";
            if (omit[x] == 0 && path[x]++ == 0)
            {
                    output = output pad x;
                    pad = ":";
            }
    }
    print output;
}'

Memoria de recuento utilizada por httpd

ps -ylC httpd | awk '/[0-9]/ {SUM += $8} END {print SUM/1024}'

O cualquier otro proceso reemplazando httpd. Dividiendo por 1024 para obtener salida en MB.

Logré construir un emulador de comando de árbol de DOS para UNIX (find + awk):

find . -type d -print 2>/dev/null|awk '{for (i=1;i< NF;i++)printf("%"length($i)"s","|");gsub(/[^\/]*\//,"--",<*>);print $NF}'  FS='/'

Imprimir líneas entre dos patrones:

awk '/END/{flag=0}flag;/START/{flag=1}' inputFile

Explicación detallada: http://nixtip.wordpress.com/2010/10/12/print-lines-between-two-patterns-the-awk-way/

Un par de favoritos, esencialmente no relacionados entre sí. Lea como 2 sugerencias diferentes, sin conexión.

Identificando fácilmente los números de columna

:

Para aquellos que usan awk con frecuencia, como lo hago para el análisis de registros en el trabajo, a menudo necesito averiguar cuáles son los números de columna para un archivo. Entonces, si estoy analizando, digamos, archivos de acceso de Apache (algunas muestras se pueden encontrar aquí ) Ejecuto el siguiente script contra el archivo:

NR == 1 {
        for (i = 1 ; i <= NF ; i++)
                {
                print i "\t" $i
                }
        }
NR > 1  {
        exit
        }

Normalmente lo llamo " cn.awk " ;, por 'c'olumn' n'umbers. Creativo, ¿eh? De todos modos, la salida se ve así:

1   64.242.88.10
2   -
3   -
4   [07/Mar/2004:16:05:49
5   -0800]
6   "GET
7   /twiki/bin/edit/Main/Double_bounce_sender?topicparent=Main.ConfigurationVariables
8   HTTP/1.1"
9   401
10  12846

Muy fácil saber qué es qué. Por lo general, alias esto en mis servidores y lo tengo en todas partes.


Hacer referencia a campos por nombre

Ahora, suponga que su archivo tiene una fila de encabezado y prefiere usar esos nombres en lugar de números de campo. Esto le permite hacerlo:

NR == 1 {
    for (i = 1 ; i <= NF ; i++)
        {
        field[$i] = i
        }
    }

Ahora, supongamos que tengo esta fila de encabezado ...

metric,time,val,location,http_status,http_request

... y me gustaría sumar la columna val . En lugar de referirme a $ 3, puedo referirme a él por su nombre:

NR > 1  {
    SUM += $field["val"]
    }

El principal beneficio es hacer que el script sea mucho más legible.

Imprimir campos es una de las primeras cosas mencionadas en la mayoría de los tutoriales de AWK.

awk '{print $1,$3}' file

Menos conocido pero igualmente útil es excluir campos que también es posible:

awk '{$1=$3=""}1' file
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top