Границы в регулярном выражении awk не работают в OpenBSD

Решение GNUAWK(для получения количества кодов стран только на текущую дату):

awk 'BEGIN{ curr_d=strftime("%d/%b/%Y", systime()) }
     $3~"^\\["curr_d{ cc[$8]++ }
     END{ for(i in cc) print i":"cc[i] }' /var/log/mywebsite.log > /home/mywebsite/www/countries.txt
6
13.01.2020, 01:26
2 ответа

Это ограничение четко задокументировано.

Из:http://man.openbsd.org/awk.1#STANDARDS

STANDARDS

The awk utility is compliant with the IEEE Std 1003.1-2008 (“POSIX.1”) specification, except awk does not support {n,m} pattern matching.

15
27.01.2020, 20:23

Я не могу поручиться за разработчиков OpenBSD, но причина, по которой границы / интервальные выражения не поддерживаются в OpenBSD и большинстве других реализаций awk , может заключаться в том, что они являются ] ужасный провал , реализация -мудрая.

Я начну с теста, используя GNU awk (gawk), который их поддерживает:

time echo | gawk '/a{1,30000}/'
  # still going strong, after 5 minutes with the CPU at 100%
  # and eating up > 4G of memory

Поскольку awk использует реальные регулярные выражения (тип состояния -машины/конечного автомата, а НЕ рекурсивный/неограниченный по пространству и времени вид с возвратом из perl ), подсчитанные повторения могут только может быть реализована посредством статического повторения подвыражения регулярного выражения в коде столько раз, сколько необходимо.

Регулярное выражение типа a{1,4}на самом деле превращается во что-то вроде a(a(aa?)?)?во время компиляции. Вы можете легко увидеть, насколько неприятным это может быть что угодно, но очень малое количество повторений :даже ничтожное /a{1,500}/займет полсекунды и много МБ памяти.


Несмотря на то, что это предписано POSIX, по состоянию на апрель 2020 г. интервальные выражения НЕ поддерживаются в awk по умолчанию из Debian 10 (Buster ), OpenBSD 6.6 и FreeBSD 12.1, а также /usr/bin/nawkиз Solaris 11. За исключением для Debian (, который использует mawk), все остальные основаны на традиционном nawk ("новом awk" ).

Помимо GNU awk, реализациями awk, поддерживающими интервальные выражения, являются awk busybox и awk по умолчанию в NetBSD и MacOS.

Предполагаемый потомок nawk(bwk , "one true awk" )также недавно включил поддержку интервальных выражений, что, по ИМХО, было абсолютно НЕ хорошо -вне.

В истории POSIX налагались невыполненные требования для awk, которые затем приходилось отменять; примером этого является требование, чтобы 0=="000"оценивалось как 1 (true ),который был удален из текущей версии стандарта, но, к сожалению, попал в /usr/xpg4/bin/awkот Solaris, что сделало его непригодным для использования.

1
12.04.2020, 21:51

Теги

Похожие вопросы