Використання grep vs awk


17

Для захоплення певного шаблону awkі grepйого можна використовувати. Чому ми повинні використовувати одне над іншим? Що швидше і чому?

Якщо у мене був файл журналу і я хотів схопити певний зразок, я міг би зробити одне з наступних

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

або

grep 'pattern' /var/log/messages

Я не робив жодного бенчмаркингу, тому не знав би. Хтось може це детальніше розробити? Чудово знати внутрішню роботу цих двох інструментів.


Попередняйте будь-яку команду, навіть сценарії оболонки, з timeкомандою, щоб визначити, скільки часу потрібно для запуску команди. Приклад: time ls -l.
Bulrush

Відповіді:


26

grep, швидше за все, буде швидшим:

# 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 - інтерпретована мова програмування, де як grep - це складена програма з кодом (яка додатково оптимізована для пошуку шаблонів у файлах).

(Примітка. Я виконував обидві команди двічі, щоб кешування потенційно не перекривило результати)

Детальніше про інтерпретовані мови у Вікіпедії.

Як справедливо зазначає Стефан у коментарях, ваш пробіг може змінюватись через реалізацію використовуваних вами греп-фуків, операційної системи, на якій він включений, та набору символів, який ви обробляєте.


2
Не кажучи про те, яку програму grep або awk ви використовуєте та на якій архітектурі комп'ютера та який набір системних символів, ці терміни мають мало значення.
Стефан Шазелас

1
друга команда також використовуватиме щойно кешовану версію. Я не сумніваюся, що grep швидше, але не на стільки, скільки показують ваші цифри.
exussum

(отже, виконуючи awk, grep, awk, grep та публікуючи результати другого набору awk та grep :) та FYI, я живу в локації UTF8.
Драв Слоун

1
Досить смішно, що інструменти BSD (на Mac), awk (31.74s) трохи швидше, ніж sed (33.34s), що трохи швидше, ніж grep (34.21s). Gnu awk володіє ними всі в 5.24, я не маю gnu grep або sed для тестування.
Кевін

1
grep повинен бути трохи швидшим, тому що awk робить більше з кожним рядком введення, ніж просто шукає в ньому повторне вираження, наприклад, якщо поле посилається на сценарій (на що це не в цьому випадку) awk розділить кожен рядок введення на поля на основі значення роздільника поля і воно заповнює вбудовані змінні. але з тим, що ви розмістили, майже не повинно бути різниці. До сих пір в найбільш важлива відмінність між Grep і AWK відповідності WRT регулярних виразів, що GREP пошук по всій лінії для узгодження рядки в той час як AWK можуть шукати певні поля і таким чином забезпечують більшу точність і менше помилкових збігів.
Ед Мортон

14

Використовуйте найбільш специфічний та виразний інструмент. Інструмент, який найкраще відповідає вашому випадку використання, швидше за все, буде найшвидшим.

Як орієнтовний посібник:

  • шукаєте рядки, які відповідають підрядковій чи повторній генерації? Використовуйте греп.
  • вибір певних стовпців із просто обмеженого файлу? Використовуйте розріз.
  • виконуючи підстановки на основі шаблону або ... інші речі sed можуть розумно зробити? Використовуйте sed.
  • Вам потрібна комбінація вищезазначених 3, або форматування printf, або петлі та гілки загального призначення? Використовуйте awk.

+1, крім використання perlзамість awk. якщо вам потрібне щось складніше, ніж grep / cut / sed, то шансів на awk буде недостатньо, і вам знадобиться щось "повноцінне"
sds

@sds чому б не замість python
RetroCode

@RetroCode: python більше "загального призначення", ніж perl; еквівалентний однолінійний, ймовірно, буде набагато довшим.
sds

3
@sds ні, perl вам не потрібен, якщо ви не збираєтеся робити щось, крім обробки тексту. awk - це чудово для тексту, що обробляє текст, який складніше, ніж grep / cut / sed і як бонус є стандартним для всіх установок UNIX, на відміну від perl.
Ед Мортон

10

Коли ви шукаєте лише рядки та значення швидкості, ви майже завжди повинні користуватися grep. Це на порядок швидше, ніж awkколи мова йде лише про грубі пошуки.

Джерело Функціональні та продуктивні відмінності sed, awk та інших утиліт для розбору 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
Дякуємо за прекрасний огляд усіх цих програм. Він справді проливає світло в темряві.
holasz

1
~ headtilt ~ PHP там, але Perl ні?
Ізката

@Izkata - те ж саме я подумав, коли побачив цей столик деякий час тому.
slm

1
Не дуже справедливо до інших утиліт, що grep просто шукає, і вони також замінюють.
Кевін

1
Це абсолютно хибні цифри. Розмова про порівнюєте яблука і апельсини - це як сказати , що ви можете тільки знайти новий автомобіль на веб - сайті A в протягом 5 секунд , тоді як ви можете знайти машину, домовитися про ціну, отримати кредит і придбати автомобіль на сайті B в протягом 1 години , так тому сайт A швидший, ніж сайт B.Зазначена вами стаття абсолютно помилкова в своїх твердженнях про відносну швидкість виконання між grep, sed і awk, і він також говорить, awk ... has PCRE matching for regular expressionsщо просто абсолютно не відповідає дійсності.
Ед Мортон

5

Хоча я згоден, що теоретично grepмає бути швидше, ніж awkна практиці YMMV, оскільки це багато в чому залежить від використання, яку ви використовуєте.

тут порівнюються греп і awk зайнятої 1.20.0, GNU grep 2.14, mawk 1.3.3, GNU awk 4.0.1 на Debian / Linux 7.0 amd64 (з glibc 2.17) у локалі UTF-8 у 240-МБ файлі 2,5М рядків Символи, призначені лише для 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 

У мові C лише греп GNU отримує значне збільшення та стає швидшим, ніж mawk.

Набір даних, тип регулярного виразу також можуть істотно змінитись. Що стосується регулярних виразів, awkслід порівнювати їх з тим, grep -Eяк awkрегулярні регепси розширені.

Цей набір даних awkможе бути швидшим, ніж grepу системах або системах на базі зайнятих ящиків, де mawkза замовчуванням awkє локаль, а за замовчуванням - UTF-8 (IIRC, це було у Ubuntu).


2

Коротше кажучи, grepробить одне лише багато інших інструментів UNIX, і це відповідність рядку заданому шаблону, і це робить добре. З іншого боку, awkце більш досконалий інструмент, оскільки це повна мова програмування, визначена стандартом POSIX з типовими функціями, такими як змінні, масиви, вирази, функції або контрольні оператори для сканування шаблону та обробки.

На мою думку, це залежить від того, наскільки реалізують обидва інструменти у разі відповідності шаблону та розмір деякого вводу, який ви хочете обробити. Я б очікував, що греп, як правило, більш ефективний, ніж awk, оскільки він робить лише відповідність. Але ви не можете писати за допомогою греппу простого коду для виконання складніших завдань, таких як подальша обробка відповідних записів, обчислення чи друк результатів без використання інших інструментів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.