Używanie grep vs awk

17

Aby uchwycić określony wzór awki grepmożna go użyć. Dlaczego powinniśmy używać jednego nad drugim? Który jest szybszy i dlaczego?

Gdybym miał plik dziennika i chciałbym pobrać określony wzór, mógłbym wykonać jedną z następujących czynności

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

lub

grep 'pattern' /var/log/messages

Nie przeprowadziłem żadnych testów porównawczych, więc nie wiedziałbym. Czy ktoś może to rozwinąć? Wspaniale jest znać wewnętrzne działanie tych dwóch narzędzi.

holasz
źródło
Poprzedź dowolne polecenie, nawet skrypty powłoki, timepoleceniem, aby określić, ile czasu zajmuje wykonanie polecenia. Np time ls -l. :
Sitowie

Odpowiedzi:

26

grep najprawdopodobniej będzie szybszy:

# 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 jest zinterpretowanym językiem programowania, w którym grep jest skompilowanym programem w kodzie c (który jest dodatkowo zoptymalizowany pod kątem wyszukiwania wzorców w plikach).

(Uwaga - uruchomiłem oba polecenia dwa razy, aby buforowanie potencjalnie nie wypaczyło wyników)

Więcej informacji na temat tłumaczonych języków na wikipedii.

Jak słusznie zauważył Stephane w komentarzach, twój przebieg może się różnić ze względu na implementację grep i awk, którego używasz, systemu operacyjnego, na którym jest on włączony, i zestawu znaków, który przetwarzasz.

Drav Sloan
źródło
2
Nie mówiąc, jakiej implementacji grep lub awk używasz i na jakiej architekturze komputera iz jakim zestawem znaków systemowych te czasy mają niewielką wartość.
Stéphane Chazelas
1
drugie polecenie użyje również nowo buforowanej wersji. Nie wątpię, że grep jest szybszy, ale nie tak bardzo, jak pokazują twoje liczby.
exussum
(stąd uruchamianie awk, grep, awk, grep i publikowanie wyników z drugiego zestawu awk i grep :) i FYI, mieszkam w lokalizacji UTF8.
Drav Sloan
1
Zabawne jest to, że dzięki narzędziom BSD (na komputerze Mac) awk (31,74 s) jest nieco szybszy niż sed (33,34 s), czyli nieco szybciej niż grep (34,21 s). Gnu awk posiada je wszystkie w 5.24s, nie mam gnu grep ani sed do przetestowania.
Kevin
1
grep powinien być nieco szybszy, ponieważ awk robi więcej z każdą linią wejściową niż po prostu wyszukuje w niej wyrażenie regularne, np. jeśli w skrypcie jest odwołanie do pola (czego nie ma w tym przypadku) awk podzieli każdą linię wejściową na pola na podstawie pole separatora pól i wypełnia wbudowane zmienne. ale z tym, co opublikowałeś, nie powinno być prawie żadnej różnicy. Zdecydowanie na najważniejszej różnicy między grep i awk wrt dopasowywania wyrażeń regularnych jest to, że wyszukiwania grep cała linia na sznurku dopasowania podczas awk mogą wyszukiwać konkretne pola i tak zapewnić większą precyzję i mniejszą liczbę fałszywych wyników.
Ed Morton,
14

Użyj najbardziej konkretnego i wyrazistego narzędzia. Narzędzie, które najlepiej pasuje do Twojego przypadku, będzie prawdopodobnie najszybsze.

Jako przybliżony przewodnik:

  • szukasz linii pasujących do podłańcucha lub wyrażenia regularnego? Użyj grep.
  • wybierasz określone kolumny z pliku z ogranicznikami? Użyj cięcia.
  • przeprowadzanie podstawień na podstawie wzorców lub ... inne rzeczy, które można racjonalnie zrobić? Użyj sed.
  • potrzebujesz kombinacji powyższych 3, formatowania printf lub pętli i gałęzi ogólnego przeznaczenia? Użyj awk.
Nieprzydatny
źródło
+1 z wyjątkiem użycia perlzamiast awk. jeśli potrzebujesz czegoś bardziej skomplikowanego niż grep / cut / sed, wówczas szanse na awk nie wystarczą i potrzebujesz czegoś „w pełni rozwiniętego”
sds
@sds dlaczego nie python zamiast
RetroCode
@RetroCode: python jest bardziej „ogólnego przeznaczenia” niż perl; równoważny jednowarstwowy będzie prawdopodobnie znacznie dłuższy.
sds
3
@ sds nie, nie potrzebujesz perla, chyba że zamierzasz zrobić coś innego niż przetwarzanie tekstu. awk nadaje się do przetwarzania tekstu, który jest bardziej skomplikowany niż grep / cut / sed, i jako bonus jest standardem we wszystkich instalacjach UNIX, w przeciwieństwie do Perla.
Ed Morton,
10

Gdy szukasz tylko ciągów znaków i prędkości, prawie zawsze powinieneś używać grep. Jest o rząd wielkości szybszy niż w awkprzypadku zwykłego wyszukiwania.

źródło Różnice funkcjonalne i wydajnościowe sed, awk i innych narzędzi parsujących Unixa

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
źródło
1
Dzięki za miły przegląd wszystkich tych programów. Naprawdę rzuca światło w ciemność.
holasz
1
~ headtilt ~ PHP jest tam, ale Perl nie?
Izkata
@Izkata - Myślałem tak samo, kiedy jakiś czas temu widziałem ten stół.
slm
1
Inne narzędzia nie są tak uczciwe, że grep tylko szuka, a one również zastępują.
Kevin
1
To są całkowicie fałszywe liczby. Dyskusja o porównywanie jabłek i pomarańczy - to tak, jakby powiedzieć można tylko znaleźć nowy samochód na stronie internetowej A w 5 sekund, podczas gdy można znaleźć samochód, negocjować cenę, dostać kredyt i zakup samochodu na miejscu B w 1 godzinę tak dlatego strona A jest szybsza niż strona B. Cytowany artykuł jest całkowicie niepoprawny w swoich oświadczeniach o względnej prędkości wykonania między grep, sed i awk, a także mówi, awk ... has PCRE matching for regular expressionsco jest całkowicie nieprawdziwe.
Ed Morton,
5

Chociaż zgadzam się, że teoretycznie greppowinien być szybszy niż awk, w praktyce, YMMV, ponieważ zależy to w dużej mierze od implementacji, której używasz.

porównując grep i awk z busybox 1.20.0, GNU grep 2.14, mawk 1.3.3, GNU awk 4.0.1 na Debian / Linux 7.0 amd64 (z glibc 2.17) w ustawieniach regionalnych UTF-8 na 240 MB pliku o wielkości 2,5M linii Znaki tylko 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 

W języku C tylko GNU grep otrzymuje znaczący wzrost i staje się szybszy niż mawk.

Zbiór danych, typ wyrażenia regularnego może również mieć duże znaczenie. W przypadku wyrażeń regularnych awknależy je porównać zgrep -E jak awk„s wyrażenia regularne są rozszerzone Res.

W przypadku tego zestawu danych awkmoże być szybszy niż grepw systemach opartych na busyboksie lub systemach, w których mawkjest to ustawienie domyślne, awka domyślne ustawienia regionalne to UTF-8 (IIRC, tak było kiedyś w Ubuntu).

Stéphane Chazelas
źródło
2

W skrócie, greprobi jedną rzecz tylko tyle samo, co wiele innych narzędzi UNIX, a to dopasowuje linię do podanego wzorca i robi to dobrze. Z drugiej strony awkjest bardziej zaawansowanym narzędziem, ponieważ jest to kompletny język programowania zdefiniowany przez standard POSIX z typowymi funkcjami, takimi jak zmienne, tablice, wyrażenia, funkcje lub instrukcje sterujące do skanowania i przetwarzania wzorów.

Moim zdaniem zależy to od implementacji wydajności obu narzędzi w przypadku dopasowania wzorca i wielkości niektórych danych wejściowych, które chcesz przetworzyć. Spodziewałbym się, że grep jest zwykle bardziej wydajny niż awk, ponieważ tylko dopasowuje. Ale nie można pisać za pomocą grep prostego kodu do wykonywania bardziej złożonych zadań, takich jak dalsze przetwarzanie dopasowanych rekordów, obliczenia lub drukowanie wyników bez użycia innych narzędzi.

dsmsk80
źródło