~ 안에이것Q&A 맨페이지 개요가 "느슨하게" 기반으로 되어 있다는 언급이 있습니다.확장된 Backus-Naur 양식메타 구문 표기법. 흥미롭고 배경 역할을 합니다. 즉, 관련 용어를 사용하면 매뉴얼의 명령 개요에서 찾을 수 있는 가장 일반적인 유형의 요소 중 하나는선택적 순서; 로 만들어진정의 목록사이에 에워싸인시작 옵션 기호그리고끝 옵션 기호. 많은 단어에서 우리는 종종 [ option ]
단일 대시 또는 하나 이상의 문자 뒤에 오는 긴 이중 대시 형식과 같은 것과 연관시킵니다(예: in ) ps --help
.
그래서 저는 실제로 매뉴얼에서 자주 볼 수 있는 일반적인 선택적 시퀀스 패턴을 일치시키고 싶습니다.
- 다음으로 시작
[
하고 다음으로 끝남]
- 에 선택적 시퀀스가 포함되어 있습니다.형태또는
-option
--option
- 반드시 괄호 안의 중앙에 위치할 필요는 없습니다. 즉
[-a]
,[ -ab]
, ,[-abc ]
모두 일치합니다. - 옵션과 옵션 요소/지정자를 포함하는 목록을 허용합니다. 즉,
[-a foo -b bar -c=biz end]
- 다른 괄호가 외부 괄호 안에 나타날 수 있도록 허용합니다. 즉
[--a [-b[-c]] -d foo]
, 여기의 전체 입력과 일치합니다.
... 하지만그렇지 않다허용하다:
---
어떠한 상황에서도 대시 3개- 더 명확하게 말하면
[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.산출맨페이지 파일을 반복하여 테스트할 수 있는 좋은 기회를 제공합니다. 여기서는 grep을 사용하여 for i in /usr/share/man/man1/*.gz; do basename "${i//.1.gz}"; my_grep_command_above <<< "$(man -l "$i")"; done
맨페이지 출력 전체를 사용했습니다. 그렇지 않으면 man man
또는 man as
테스트를 위한 선택적 시퀀스의 좋은 변형을 제공합니다.
답변1
grep
(GNU를 사용하여 ) 다음을 수행할 수 있습니다 .
grep -Po '\[\s*--?(?!-)((?>[^][]+)|\[(?1)*\])+\]'
귀하의 질문 내용에 따르면 다음과 같습니다.
[-a]
[ -ab]
[-abc ]
[-a foo -b bar -c=biz end]
[--a [-b[-c]] -d foo]
pcrepattern(3)
중첩 일치에 대해 설명된 대로 PCRE와 재귀 일치 연산자를 사용하는 아이디어입니다 [...]
.