OpenBSD에서 작동하지 않는 awk 정규식의 경계

OpenBSD에서 작동하지 않는 awk 정규식의 경계

이 awk 표현식은 inet 34.45OpenBSD에서 예상대로 인쇄됩니다.

echo "inet 34.45" | awk '/inet [0-9]+\./ { print }'

그러나 +the 를bound 로 바꾸면 {1,3}일치하는 항목이 없습니다.

echo "inet 34.45" | awk '/inet [0-9]{1,3}\./ { print }'

두 표현 모두 Linux의 gawk에서 잘 작동합니다. gawk 매뉴얼 페이지에는 awk가 처음에는 간격 표현식을 지원하지 않았지만 나중에 egrep과 일관성을 유지하기 위해 POSIX에 추가되었다고 언급되어 있습니다. OpenBSD의 awk 매뉴얼 페이지에서는 그러한 내용을 언급하지 않고 단지 평소와 같이 범위를 지정하는 re_format에 대한 매뉴얼 페이지를 인용합니다.

이것은 OpenBSD awk의 버그입니까, 아니면 문서화되지 않은 제한 사항입니까?

답변1

이 제한 사항은 명확하게 문서화되어 있습니다.

에서:http://man.openbsd.org/awk.1#STANDARDS

기준

awk 유틸리티는 IEEE Std 1003.1-2008("POSIX.1") 사양을 준수하지만 awk는 {n,m} 패턴 일치를 지원하지 않습니다.

답변2

OpenBSD 사람들을 보증할 수는 없지만 제한할 이유가 있습니다.간격 표현OpenBSD 및 대부분의 다른 awk 구현은 지원하지 않습니다.가능한왜냐하면 그들은끔찍한 혼란, 구현 측면.

gawk이를 지원하는 GNU awk( )를 사용하여 테스트 사례부터 시작하겠습니다 .

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}/0.5초와 많은 MB의 메모리가 필요합니다.


POSIX 규정에도 불구하고 2020년 4월 현재 Debian 10(Buster), OpenBSD 6.6, FreeBSD 12.1, Solaris 11의 기본 awk는 간격 표현식을 지원하지 않습니다. /usr/bin/nawkDebian(사용 중 ) mawk을 제외한 다른 모든 레거시 nawk 기반("new awk") .

GNU awk 외에도 간격 표현식을 지원하는 다른 awk 구현에는 busybox awk와 NetBSD 및 MacOS의 기본 awk가 포함됩니다.

노크(Knock)의 후손이라고 전해진다.부커, "진짜 이상한") 최근에도포함하다IMHO가 확실히 잘 생각하지 못한 움직임인 간격 표현식을 지원합니다.

POSIX는 역사적으로 중단되어 더 이상 사용되지 않는 awk에 대한 요구 사항을 시행했습니다. 한 가지 예는 0=="000"1(true)로 평가되어야 하는 요구 사항입니다.떨어지다현재 버전의 표준에는 있지만 불행히도 /usr/xpg4/bin/awkSolaris에서 이식되어 사용할 수 없게 되었습니다.

관련 정보