Utilizzando grep vs awk


17

Per acquisire un modello particolare awke greppuò essere utilizzato. Perché dovremmo usare l'uno sull'altro? Qual è più veloce e perché?

Se avessi un file di registro e volessi acquisire un determinato modello, potrei eseguire una delle seguenti operazioni

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

o

grep 'pattern' /var/log/messages

Non ho fatto alcun benchmarking, quindi non lo saprei. Qualcuno può elaborarlo? È bello conoscere il funzionamento interno di questi due strumenti.


Precede qualsiasi comando, anche gli script di shell, con il timecomando per indicare il tempo impiegato per eseguire il comando. Es: time ls -l.
Bulrush,

Risposte:


26

molto probabilmente grep sarà più veloce:

# 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 è un linguaggio di programmazione interpretato, in cui grep è un programma c-code compilato (che è ulteriormente ottimizzato per trovare schemi nei file).

(Nota: ho eseguito entrambi i comandi due volte in modo che la memorizzazione nella cache non alterasse potenzialmente i risultati)

Maggiori dettagli sulle lingue interpretate su wikipedia.

Come Stephane ha giustamente sottolineato nei commenti, il tuo chilometraggio può variare a causa dell'implementazione del grep e del awk che usi, del sistema operativo su cui si trova e del set di caratteri che stai elaborando.


2
Senza dire quale implementazione grep o awk stai usando e su quale architettura di computer e con quale set di caratteri di sistema, quei tempi hanno poco valore.
Stéphane Chazelas,

1
il secondo comando utilizzerà anche la versione appena memorizzata nella cache. Non ho dubbi sul fatto che grep sia più veloce ma non tanto quanto i tuoi numeri mostrano.
exussum,

(quindi eseguendo awk, grep, awk, grep e pubblicando i risultati dal secondo set di awk e grep :) e FYI, vivo in una località UTF8.
Drav Sloan,

1
Abbastanza divertente, con gli strumenti BSD (su un Mac), awk (31.74s) è leggermente più veloce di sed (33.34s), che è leggermente più veloce di grep (34.21s). Gnu awk li possiede tutti a 5.24s, non ho gnu grep o sed da testare.
Kevin,

1
grep dovrebbe essere leggermente più veloce perché awk fa di più con ogni riga di input piuttosto che cercare una regexp al suo interno, ad esempio se un campo viene referenziato nello script (cosa che non è in questo caso) awk dividerà ogni riga di input in campi basati sul valore del separatore di campo e popola le variabili incorporate. ma con quello che hai pubblicato non dovrebbe esserci quasi alcuna differenza. Di gran lunga la più importante differenza tra grep e awk espressioni regolari WRT corrispondenza è che le ricerche di grep tutta la linea per una stringa corrispondente, mentre awk può cercare campi specifici e così fornire maggiore precisione e un minor numero di false corrispondenze.
Ed Morton,

14

Utilizza lo strumento più specifico ed espressivo. Lo strumento più adatto al tuo caso d'uso è probabilmente il più veloce.

Come guida approssimativa:

  • alla ricerca di linee corrispondenti a una sottostringa o regexp? Usa grep.
  • selezionando determinate colonne da un file delimitato semplicemente? Usa il taglio.
  • eseguendo sostituzioni basate su schemi o ... altre cose che sed può ragionevolmente fare? Usa sed.
  • hai bisogno di una combinazione dei 3 precedenti, o della formattazione di printf o di loop e rami per uso generale? Usa awk.

+1 tranne usare perlinvece di awk. se hai bisogno di qualcosa di più complicato di grep / cut / sed, allora le probabilità che siano pazzi non saranno sufficienti e hai bisogno di qualcosa di "completo"
sds

@sds why not python invece
RetroCode

@RetroCode: python è più "generico" di perl; l'equivalente one-liner sarà probabilmente molto più lungo.
sds,

3
@sds no, non hai bisogno di perl a meno che tu non abbia intenzione di fare qualcosa di diverso dall'elaborazione del testo. awk va bene per le cose di elaborazione del testo che sono più complicate di grep / cut / sed e come bonus arriva di serie su tutte le installazioni UNIX, a differenza di perl.
Ed Morton,

10

Quando cerchi solo stringhe e la velocità è importante, dovresti quasi sempre usarla grep. È ordini di grandezza più veloci di awkquando si tratta solo di ricerche grossolane.

source Le differenze funzionali e prestazionali delle utility di analisi sed, awk e 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

1
Grazie per questa bella panoramica di tutti questi programmi. Fa davvero luce nell'oscurità.
holasz,

1
~ headtilt ~ PHP è lì ma Perl no?
Izkata,

@Izkata - Ho pensato la stessa cosa quando ho visto questo tavolo qualche tempo fa.
slm

1
Non è proprio giusto per gli altri programmi di utilità che grep sta solo cercando e stanno anche sostituendo.
Kevin,

1
Quelli sono numeri completamente falsi. Parlare di confrontare le mele e arance - è come dire che si può solo in 5 secondi trovare una nuova auto sul sito web A, mentre è possibile trovare una macchina, negoziare un prezzo, ottenere un prestito, e acquistare l'auto in loco B in 1 ora in modo quindi il sito A è più veloce del sito B. L'articolo che hai citato è completamente sbagliato nelle sue dichiarazioni di velocità di esecuzione relativa tra grep, sed e awk e dice anche awk ... has PCRE matching for regular expressionsche è completamente falso.
Ed Morton,

5

Mentre sono d'accordo che in teoria grepdovrebbe essere più veloce di awk, in pratica, YMMV in quanto ciò dipende molto dall'implementazione che usi.

qui confrontando grep e awk di busybox 1.20.0, GNU grep 2.14, mawk 1.3.3, GNU awk 4.0.1 su Debian / Linux 7.0 amd64 (con glibc 2.17) in una localizzazione UTF-8 su un file 240 MB di 2,5 MB di righe di Caratteri 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 

Nella localizzazione C, solo GNU grep ottiene una spinta significativa e diventa più veloce di mawk.

Il set di dati, il tipo di regexp può anche fare una grande differenza. Per espressioni regolari, awkdovrebbe essere paragonato a grep -Ecome awk's espressioni regolari sono ER estesi.

Per questo set di dati, awkpotrebbe essere più veloce rispetto grepai sistemi basati su busybox o ai sistemi in cui mawkè l'impostazione predefinita awke l'impostazione internazionale predefinita è basata su UTF-8 (IIRC, era il caso di Ubuntu).


2

In poche parole, grepfa una cosa solo come molti altri strumenti UNIX e questo è abbinare una linea al modello dato e lo fa bene. D'altra parte, awkè uno strumento più sofisticato in quanto è un linguaggio di programmazione completo definito dallo standard POSIX con caratteristiche tipiche come variabili, array, espressioni, funzioni o istruzioni di controllo per la scansione e l'elaborazione dei pattern.

A mio avviso, dipende dall'implementazione delle prestazioni di entrambi gli strumenti in caso di pattern matching e dalla dimensione di alcuni input che si desidera elaborare. Mi aspetterei che grep sia di solito più efficiente di awk poiché corrisponde solo. Ma non è possibile scrivere con grep un semplice codice per eseguire attività più complesse come l'ulteriore elaborazione di record corrispondenti, il calcolo o la stampa dei risultati senza utilizzare altri strumenti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.