Использование grep против awk

17

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

Если бы у меня был файл журнала, и я хотел получить определенный шаблон, я мог бы сделать одно из следующего

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

или

grep 'pattern' /var/log/messages

Я не делал никаких тестов, поэтому я бы не знал. Может кто-нибудь уточнить это? Приятно знать внутреннюю работу этих двух инструментов.

holasz
источник
Перед любой командой, даже сценариями оболочки, указывается timeвремя, необходимое для выполнения команды. Пример: time ls -l.
камыш

Ответы:

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 - это скомпилированная программа c-кода (которая дополнительно оптимизирована для поиска шаблонов в файлах).

(Примечание: я выполнил обе команды дважды, чтобы кэширование не могло исказить результаты)

Подробнее о переводимых языках в Википедии.

Как правильно заметил Стефан в комментариях, ваш пробег может отличаться из-за использования используемых вами grep и awk, операционной системы и набора символов, который вы обрабатываете.

Драв Слоан
источник
2
Не говоря уже о том, какую реализацию grep или awk вы используете и на какой архитектуре компьютера и с каким набором символов системы, эти временные характеристики не имеют большого значения.
Стефан Шазелас
1
вторая команда также будет использовать недавно кэшированную версию. Я не сомневаюсь, что grep быстрее, но не настолько, как показывают ваши цифры.
Exussum
(следовательно, запускаю awk, grep, awk, grep и публикую результаты из второго набора awk и grep :) и к вашему сведению, я живу в локали UTF8.
Драв Слоан
1
Забавно, но с инструментами BSD (на Mac) awk (31,74 с) немного быстрее, чем sed (33,34 с), что немного быстрее, чем grep (34,21 с). Gnu awk владеет ими на 5.24, у меня нет gnu grep или sed для тестирования.
Кевин
1
grep должен быть немного быстрее, потому что awk делает больше с каждой входной строкой, чем просто ищет в ней регулярное выражение, например, если в скрипте есть ссылка на поле (чего нет в этом случае) awk разделит каждую входную строку на поля на основе значение разделителя полей и оно заполняет встроенные переменные. но с тем, что вы разместили, не должно быть почти никакой разницы. До сих пор в наиболее важное различие между Grep и AWK соответствия WRT регулярных выражений, что GREP поиск по всей линии для согласования строки в то время как AWK могут искать определенные поля и таким образом обеспечивают большую точность и меньше ложных совпадений.
Эд Мортон
14

Используйте самый конкретный и выразительный инструмент. Инструмент, который лучше всего подходит для вашего случая использования, вероятно, будет самым быстрым.

Как грубое руководство:

  • поиск строк, соответствующих подстроке или регулярному выражению? Используйте grep.
  • выбрать определенные столбцы из файла с разделителями? Используйте вырезать.
  • выполнение подстановок на основе шаблонов или ... другие вещи, которые может разумно делать sed? Используйте сед.
  • нужна какая-то комбинация вышеуказанных 3, или форматирование printf, или циклы и ветви общего назначения? Используйте awk.
Бесполезный
источник
+1 кроме использования perlвместо awk. если вам нужно что-то более сложное, чем grep / cut / sed, то шансов на awk будет недостаточно, и вам нужно что-то «полноценное»
sds
@sds, почему бы не использовать Python
RetroCode
@RetroCode: python более универсален, чем perl; Эквивалентный однострочник, вероятно, будет намного длиннее.
Сд
3
@sds нет, вам не нужен Perl, если вы не собираетесь делать что-то кроме обработки текста. awk отлично подходит для обработки текста, более сложной, чем grep / cut / sed, и в качестве бонуса входит в стандартную комплектацию всех установок UNIX, в отличие от perl.
Эд Мортон
10

Когда поиск только по строкам, а скорость имеет значение, вы должны почти всегда использовать grep. Это на несколько порядков быстрее, чем awkкогда дело доходит до грубого поиска.

source Различия в функциональности и производительности 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
SLM
источник
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, так как это во многом зависит от используемой вами реализации.

здесь сравниваются grep и awk busybox 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 grep получает значительное ускорение и становится быстрее, чем mawk.

Набор данных, тип регулярного выражения также может иметь большое значение. Для регулярных выражений, awkследует сравнить , grep -Eкак awkрегэксп «S являются расширенными УЭ.

Для этого набора данных awkможет быть быстрее, чем grepв системах на основе busybox, где mawkпо умолчанию awkиспользуется стандарт, а языковой стандарт по умолчанию - на основе UTF-8 (IIRC, как это было в Ubuntu).

Стефан Шазелас
источник
2

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

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

dsmsk80
источник