수동 요약에서 특정 형태의 선택적 시퀀스(변형 포함)를 일치시키는 방법은 무엇입니까?

수동 요약에서 특정 형태의 선택적 시퀀스(변형 포함)를 일치시키는 방법은 무엇입니까?

존재하다이것Q&A에는 다음을 기반으로 "느슨하게" 참조 매뉴얼 페이지 개요가 있습니다.확장된 Backus-Knoll 패러다임메타그램적 표현. 재미 있고 배경 역할을합니다. 즉, 관련 용어를 사용하면 매뉴얼의 명령 개요에서 찾을 수 있는 가장 일반적인 요소 유형 중 하나는 다음과 같습니다.선택적 주문;에 의해정의 목록사이에 에워싸인시작 옵션 기호그리고끝 옵션 기호. 많은 단어에서 우리는 이를 유사한 와 연관시키는 경우가 많습니다 [ option ]. 이는 단일 대시 또는 긴 이중 대시 형식 뒤에 하나 이상의 문자가 올 수 있습니다 ps --help.


그래서 매뉴얼에서 자주 볼 수 있는 일반적인 선택적 시퀀스 패턴을 일치시키고 싶습니다.

  • 로 시작 [하고 로 끝난다]
  • 선택적 시퀀스를 포함합니다.형태또는-option--option
  • 괄호 안에 반드시 중앙에 위치할 필요는 없습니다 [-a]. 즉, 는 [ -ab]모두 [-abc ]와 일치합니다.
  • 옵션과 옵션 요소/지정자를 포함하는 목록이 허용됩니다.[-a foo -b bar -c=biz end]
  • 다른 괄호가 외부 괄호 안에 표시되도록 허용합니다. 즉, [--a [-b[-c]] -d foo](여기서 전체 입력과 일치합니다)

... 하지만아니요허용하다:

  • ---어쨌든 대시 세 개
  • 더 명확하게 말하면 [option](대시 없이) 및 [], [-]또는 단독으로 일치해서는 안 됩니다.[--][foo-bar=a]

데이터에는 위에 제공된 예와 같이 너무 많은 변칙 사항이 포함되어 있지 않습니다.거래일치하지 않는 괄호도 있지만 이는 이 문서의 범위를 벗어납니다. grep돌이켜보면 아마도 나처럼 요구 사항을 해결하려고 시도하는 것이 최선의 아이디어는 아니었을 것입니다. 하지만 다음과 같이 시도했습니다.

grep -E '\[{1,}([[:space:]]{0,}[[:punct:]]{0,}[[:alnum:]]{0,}){0,}(-{1,2}[[:alpha:]]{1,}){1,}([[:alnum:]]{0,}[[:punct:]]{0,}[[:space:]]{0,}){0,}\]{1,}'

어떤 패턴 1 과 일치 하고 내가 원하는 것을 수행하지만 관리 및 재사용이 어렵다는 단점이 있습니다. "청크"를 생성하기 위해 일치하는 반복을 관리하기 위해 임의의 대괄호 세트(3)를 사용하여 항목을 그룹화하는 것도 이 점에서는 도움이 되지 않습니다(그러나 디버깅에는 도움이 됩니다). 입력을 제공하기 위해 문자 클래스를 사용하는 것은 다소 예측할 수 없는 것처럼 보입니다.

그렇다면 더 나은 표현 및/또는 다른 도구/접근 방식을 사용하여 이를 어떻게 수행할 수 있습니까? 이렇게 긴 정규식을 사용하는 경우 이를 어떻게 관리합니까? 어떤 경우 콘텐츠를 필터링하기 위해 명령을 여러 번 사용해야 합니까? 이 문제를 해결하는 데 도움이 되도록 사전에 콘텐츠를 다르게 조작해야 합니까?


1. 중산출매뉴얼 페이지 파일을 반복하면 훌륭한 테스트 기회가 제공됩니다. 여기에서는 for i in /usr/share/man/man1/*.gz; do basename "${i//.1.gz}"; my_grep_command_above <<< "$(man -l "$i")"; done전체 맨페이지 출력을 사용하여 grep을 사용했습니다 . 그렇지 않으면 man man테스트 man as를 위해 대체 시퀀스의 좋은 변형을 제공하십시오.

답변1

다음과 같이 할 수 있습니다(GNU 사용 grep).

grep -Po '\[\s*--?(?!-)((?>[^][]+)|\[(?1)*\])+\]'

귀하의 질문에 다음과 같은 내용이 나와 있습니다.

[-a]
[ -ab]
[-abc ]
[-a foo -b bar -c=biz end]
[--a [-b[-c]] -d foo]

아이디어는 pcrepattern(3)일치 중첩에 설명된 대로 PCRE와 해당 재귀 일치 연산자를 사용하는 것입니다 [...].

관련 정보