Usando grep vs awk

17

Para capturar un patrón particular, awky greppuede ser utilizado. ¿Por qué deberíamos usar uno sobre el otro? ¿Cuál es más rápido y por qué?

Si tuviera un archivo de registro y quisiera obtener un cierto patrón, podría hacer uno de los siguientes

awk '/pattern/' /var/log/messages

o

grep 'pattern' /var/log/messages

No he hecho ninguna evaluación comparativa, por lo que no lo sabría. ¿Alguien puede elaborar esto? Es genial conocer el funcionamiento interno de estas dos herramientas.

holasz
fuente
Preceda cualquier comando, incluso los scripts de shell, con el timecomando para medir el tiempo que se tarda en ejecutar el comando. Ej: time ls -l.
Bulrush

Respuestas:

26

grep probablemente será más rápido:

# time awk '/USAGE/' imapd.log.1 | wc -l
73832

real    0m2.756s
user    0m2.740s
sys     0m0.020s

# time grep 'USAGE' imapd.log.1 | wc -l
73832

real    0m0.110s
user    0m0.100s
sys     0m0.030s

awk es un lenguaje de programación interpretado, donde grep es un programa compilado de código c (que además está optimizado para encontrar patrones en archivos).

(Nota: ejecuté ambos comandos dos veces para que el almacenamiento en caché no sesgue los resultados)

Más detalles sobre los idiomas interpretados en wikipedia.

Como Stephane ha señalado correctamente en los comentarios, su kilometraje puede variar debido a la implementación del grep y awk que usa, el sistema operativo en el que se encuentra y el conjunto de caracteres que está procesando.

Drav Sloan
fuente
2
Sin decir qué implementación grep o awk está utilizando y en qué arquitectura de computadora, y con qué conjunto de caracteres del sistema, esos tiempos tienen poco valor.
Stéphane Chazelas
1
el segundo comando también usará la versión recién almacenada en caché. No dudo que grep es más rápido pero no tanto como muestran sus números.
exussum
(de ahí que ejecute awk, grep, awk, grep y publique los resultados del segundo conjunto de awk y grep :) y para su información, vivo en un entorno local UTF8.
Drav Sloan
1
Curiosamente, con las herramientas BSD (en una Mac), awk (31.74s) es ligeramente más rápido que sed (33.34s), que es un poco más rápido que grep (34.21s). Gnu awk los posee a todos a las 5.24s, no tengo gnu grep o sed para probar.
Kevin
1
grep debería ser un poco más rápido porque awk hace más con cada línea de entrada que simplemente buscar una expresión regular en ella, por ejemplo, si se hace referencia a un campo en el script (que no es en este caso) awk dividirá cada línea de entrada en campos basados ​​en el valor de separador de campo y llena las variables incorporadas. pero con lo que publicaste casi no debería haber diferencia. Con mucho, la diferencia más importante entre grep y awk wrt con expresiones regulares es que grep busca en toda la línea una cadena coincidente, mientras que awk puede buscar campos específicos y, por lo tanto, proporciona más precisión y menos coincidencias falsas.
Ed Morton
14

Utiliza la herramienta más específica y expresiva. Es probable que la herramienta que mejor se adapte a su caso de uso sea la más rápida.

Como una guía aproximada:

  • buscando líneas que coincidan con una subcadena o expresión regular? Usa grep.
  • seleccionando ciertas columnas de un archivo simplemente delimitado? Use corte.
  • realizar sustituciones basadas en patrones u ... otras cosas que sed puede hacer razonablemente? Use sed.
  • ¿Necesita alguna combinación de los 3 anteriores, o el formato printf, o bucles y ramas de uso general? Usa awk.
Inútil
fuente
+1 excepto uso en perllugar de awk. si necesita algo más complicado que grep / cut / sed, entonces es probable que awk no sea suficiente y necesite algo "completo"
sds
@sds por qué no python en su lugar
RetroCode
@RetroCode: python tiene más "propósito general" que perl; el equivalente de una línea probablemente será mucho más largo.
sds el
3
@sds no, no necesita Perl a menos que vaya a hacer algo más que el procesamiento de texto. awk está bien para las cosas de procesamiento de texto que son más complicadas que grep / cut / sed y como beneficio adicional viene de serie en todas las instalaciones de UNIX, a diferencia de perl.
Ed Morton
10

Cuando solo busca cadenas y la velocidad es importante, casi siempre debe usarla grep. Es un orden de magnitud más rápido que awkcuando se trata de una búsqueda grosera.

fuente Las diferencias funcionales y de rendimiento de sed, awk y otras utilidades de análisis Unix

UTILITY    OPERATION TYPE      EXECUTION TIME     CHARACTERS PROCESSED PER SECOND
                               (10 ITERATIONS)
-------    --------------      ---------------    -------------------------------
grep       search only         41 sec.            489.3 million
sed        search & replace    4 min. 4 sec.      82.1 million
awk        search & replace    4 min. 46 sec.     69.8 million
Python     search & replace    4 min. 50 sec.     69.0 million
PHP        search & replace    15 min. 44 sec.    21.2 million
slm
fuente
1
Gracias por esta buena descripción de todos estos programas. Realmente arroja luz en la oscuridad.
holasz
1
~ headtilt ~ PHP está ahí pero Perl no?
Izkata
@Izkata - Pensé lo mismo cuando vi esta mesa hace un tiempo.
slm
1
No es justo para las otras utilidades que grep solo está buscando y también están reemplazando.
Kevin
1
Esos son números completamente falsos. Hable sobre comparar manzanas y naranjas: es como decir que solo puede encontrar un automóvil nuevo en el sitio web A en 5 segundos, mientras que puede encontrar un automóvil, negociar un precio, obtener un préstamo y comprar el automóvil en el sitio B en 1 hora, por lo que por lo tanto, el sitio A es más rápido que el sitio B. El artículo que citó está completamente equivocado en sus declaraciones de velocidad de ejecución relativa entre grep, sed y awk y también dice awk ... has PCRE matching for regular expressionscuál es completamente falso.
Ed Morton
5

Si bien estoy de acuerdo en que en teoría grepdebería ser más rápido que awk, en la práctica, YMMV ya que eso depende mucho de la implementación que use.

aquí comparando grep y awk de busybox 1.20.0, GNU grep 2.14, mawk 1.3.3, GNU awk 4.0.1 en Debian / Linux 7.0 amd64 (con glibc 2.17) en un entorno local UTF-8 en un archivo de 240 MB de líneas de 2.5M Caracteres solo ASCII.

$ time busybox grep error error | wc -l
331003
busybox grep error error  8.31s user 0.12s system 99% cpu 8.450 total
wc -l  0.07s user 0.11s system 2% cpu 8.448 total
$ time  busybox awk /error/ error | wc -l
331003
busybox awk /error/ error  2.39s user 0.84s system 98% cpu 3.265 total
wc -l  0.12s user 1.23s system 41% cpu 3.264 total
$ time  grep error error | wc -l
331003
grep error error  0.80s user 0.10s system 99% cpu 0.914 total
wc -l  0.00s user 0.11s system 12% cpu 0.913 total
$ time mawk /error/ error | wc -l
330803
mawk /error/ error  0.54s user 0.13s system 91% cpu 0.732 total
wc -l  0.03s user 0.08s system 14% cpu 0.731 total
$ time gawk /error/ error | wc -l
331003
gawk /error/ error  1.37s user 0.12s system 99% cpu 1.494 total
wc -l  0.04s user 0.07s system 7% cpu 1.492 total
$ time 

En la configuración regional C, solo GNU grep recibe un impulso significativo y se vuelve más rápido que mawk.

El conjunto de datos, el tipo de expresión regular también puede hacer una gran diferencia. Para las expresiones regulares, awkdebe compararse con las expresiones regulares grep -Ecomo awklas expresiones regulares extendidas.

Para este conjunto de datos, awkpodría ser más rápido que grepen los sistemas basados ​​en busybox o sistemas donde mawkel valor predeterminado awky la configuración regional predeterminada se basa en UTF-8 (IIRC, solía ser el caso en Ubuntu).

Stéphane Chazelas
fuente
2

En pocas palabras, grephace una cosa solo como muchas otras herramientas de UNIX y es hacer coincidir una línea con el patrón dado y lo hace bien. Por otro lado, awkes una herramienta más sofisticada, ya que es un lenguaje de programación completo definido por el estándar POSIX con características típicas como variables, matrices, expresiones, funciones o declaraciones de control para el escaneo y procesamiento de patrones.

En mi opinión, depende de la implementación del rendimiento de ambas herramientas en caso de coincidencia de patrones y del tamaño de alguna entrada que desee procesar. Esperaría que grep sea generalmente más eficiente que awk, ya que solo coincide. Pero no puede escribir con grep un código simple para realizar tareas más complejas, como el procesamiento posterior de registros coincidentes, el cálculo o la impresión de resultados sin utilizar otras herramientas.

dsmsk80
fuente