Para capturar un patrón en particular, awk
y grep
se puede utilizar. ¿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 tomar un patrón determinado, podría hacer una de las siguientes
awk "/pattern/" /var/log/messages
o
grep "pattern" /var/log/messages
No he realizado 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.
Comentarios
Respuesta
grep probablemente sea 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, mientras que grep es un programa de código c compilado (que además está optimizado para encontrar patrones en archivos) .
(Nota: ejecuté ambos comandos dos veces para que el almacenamiento en caché no desvirtuara potencialmente los resultados)
Más detalles sobre idiomas interpretados en wikipedia.
Como Stephane ha señalado correctamente en los comentarios, su kilometraje puede variar debido a la implementación de grep y awk que utiliza, el sistema operativo en el que se encuentra y el conjunto de caracteres que utiliza están procesando.
Comentarios
- Sin decir qué implementación grep o awk está ‘ usando y en qué arquitectura de computadora, y con qué sistema de caracteres del sistema, esos tiempos tienen poco valor.
- el segundo comando también usará el nuevo versión en caché. No dudo que grep es más rápido, pero no tanto como muestran sus números.
- (por lo tanto, ejecute awk, grep, awk, grep y publique los resultados del segundo conjunto de awk y grep 🙂 y para su información , Vivo en una configuración regional UTF8.
- Es bastante curioso, con las herramientas BSD (en una Mac), awk (31.74s) es un poco más rápido que sed (33.34s), que es un poco más rápido que grep ( 34,21 s). Gnu awk los posee todos en 5.24s, yo no ‘ no tengo gnu grep o sed para probar.
- grep debería ser un poco más rápido porque awk hace más con cada uno línea de entrada que simplemente buscar una expresión regular en ella, por ejemplo si se hace referencia a un campo en la secuencia de comandos (que ‘ no es en este caso) awk dividirá cada línea de entrada en campos según el valor del separador de campo y rellenará las variables integradas. pero con lo que publicaste no debería haber casi ninguna diferencia. Con mucho, la diferencia más importante entre grep y awk wrt coincidencias con expresiones regulares es que grep busca en toda la línea una cadena coincidente, mientras que awk puede buscar campos específicos y así proporcionar más precisión y menos coincidencias falsas.
Responder
Utilice 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 guía aproximada:
- ¿busca líneas que coincidan con una subcadena o una expresión regular? Utilice grep.
- ¿selecciona ciertas columnas de un archivo delimitado simplemente? Use cut.
- realizando sustituciones basadas en patrones u … ¿otras cosas que sed pueda hacer razonablemente? Use sed.
- ¿necesita alguna combinación de los 3 anteriores, o formato printf, o bucles y ramas de propósito general? Use awk.
Comentarios
- +1 excepto que use
perl
en lugar deawk
. si necesita algo más complicado que grep / cut / sed, entonces es probable que awk no ‘ sea suficiente y necesite algo » completo -blown » - @sds por qué no Python en su lugar
- @RetroCode: Python es más » propósito general » que perl; el equivalente de una sola línea probablemente será mucho más largo.
- @sds no, no ‘ no necesita Perl a menos que ‘ vas a hacer algo más que el procesamiento de texto. awk está bien para el procesamiento de texto que ‘ es más complicado que grep / cut / sed y como beneficio adicional viene de serie en todas las instalaciones de UNIX, a diferencia de perl.
Respuesta
Cuando solo busca cadenas, y la velocidad importa, casi siempre debe usar grep
. Es órdenes de magnitud más rápido que awk
cuando se trata de búsquedas brutas.
source Las diferencias funcionales y de rendimiento de sed, awk y otras utilidades de análisis de 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
Comentarios
- Gracias por esta buena descripción general de todos estos programas. Realmente arroja luz en la oscuridad.
- ~ headtilt ~ PHP está ahí pero Perl no ‘ t?
- ¿A qué
grep
y a quéawk
te refieres? - Es ‘ s no es realmente justo para las otras utilidades que grep está buscando y que también están reemplazando.
- Esos son números completamente falsos. Hable acerca de 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 el sitio A es más rápido que el sitio B. El artículo que citó está completamente equivocado ‘ s de velocidad de ejecución relativa entre grep, sed y awk y también dice
awk ... has PCRE matching for regular expressions
que es completamente falso.
Respuesta
Aunque estoy de acuerdo en que, en teoría, grep
debería ser más rápido que awk
, en la práctica, YMMV depende mucho de la implementación que utilice.
Aquí comparamos 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 una configuración regional UTF-8 en un archivo de 240 MB de 2,5 millones de líneas de 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 C locale, solo GNU grep obtiene 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, awk
debe compararse con grep -E
ya que las awk
«s son RE extendidas .
Para este conjunto de datos, awk
podría ser más rápido que grep
en sistemas basados en busybox o sistemas donde mawk
es el awk
predeterminado y la configuración regional predeterminada está basada en UTF-8 (IIRC, solía ser el caso en Ubuntu).
Respuesta
En pocas palabras, grep
hace una sola cosa como muchas otras herramientas UNIX y eso «s hacer coincidir una línea con el patrón dado y lo hace bien. Por otro lado, awk
es 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 escaneo de patrones y Procesando.
En mi opinión, depende de la implementación cómo funcionan 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 usar otras herramientas.
time
para medir el tiempo que se tarda en ejecutar el comando. Por ejemplo:time ls -l
.