$ grep '[^az]\{22\}' /usr/share/dict/words 출력 없음

$ grep '[^az]\{22\}' /usr/share/dict/words 출력 없음

실행 후

grep '[a-z]\{22\}' /usr/share/dict/words

출력은 다음과 같습니다

counterrevolutionaries
electroencephalographs

하지만 실행할 때

grep '[^a-z]\{22\}' /usr/share/dict/words

출력이 없습니다.

나는 그것이 다음과 같은 것을 생산할 것으로 예상했습니다.

grep -v '[a-z]\{22\}' /usr/share/dict/words

내 질문은 무엇이 잘못되었으며 그 이유는 무엇입니까?

답변1

[specification]정렬 요소(로케일 정렬 알고리즘에 정의된 문자 또는 문자 시퀀스일 수 있음(예: GNU 시스템의 헝가리 로케일에서 dzs및 사이에 정렬된 정렬 요소)) 와 일치합니다.de지정됨놓다.

사양에는 다음이 포함될 수 있습니다.

  • (or) 와 같은 범위는 및 사이에 정렬된 요소를 a-z대조하는 데 사용됩니다 [.dzs.]-z(일반적으로 abcdefghijklmnoprstuvwxyz를 포함하지만 대부분의 로케일에서는 훨씬 더 많은 것을 포함합니다). 또한 POSIX는 POSIX 로케일 이외의 로케일을 지정하지 않기 때문에 이러한 범위가 조합 순서를 기반으로 하는 정도는 구현마다 크게 다릅니다.az
  • 단일 문자 또는 대조 요소( x, [.dsz.])
  • POSIX 문자 클래스 [:alpha:],[:digit:]
  • [=e=]기본 데이터 정렬 가중치가 동일한 모든 데이터 정렬 요소 와 같은 등가 클래스 e(다음과 같은 항목이 포함될 수 있음 é)

예를 들어 [acd[=e=]h-k[:digit:][.dzs.]]조합 요소의 일치 항목이 , 또는 ac같 거나 과 사이에 조합된 경우 분류는 다음과 같습니다 .ddzsehk숫자.

사양이 로 시작하면 ^여전히 데이터 정렬 요소와 일치하지만 집합을 보완합니다. 이는 지정된 요소가 아닌 모든 데이터 정렬 요소입니다.

따라서 는 및 사이에 정렬되지 않은 [^a-z]모든 조합 요소와 일치합니다 . 예를 들어 로케일 및 구현에 따라 일치하거나 일치하지 않을 수 있는 및 와 일치할 수 있지만 에서는 일치 하거나 일치 하지 않을 수 있습니다 .az1XDSZgrepaxzé

그래서 grep '[^a-z]\{22\}'일치하는 라인포함하다데이터 정렬 앞이나 뒤에 오는 22일련의 조합 요소입니다.az

While 은 및 사이에 정렬된 22개의 조합 요소 시퀀스를 포함하지 않는 행 grep -v '[a-z]\{22\}'과 일치합니다 .az

동일한 요소를 일치시키는 것은 거의 불가능합니다. 두 요소 사이에 정렬된 요소가 21개 이하인 줄을 -v일치시켜야 합니다 . 그러나 로케일이 다중 문자 조합 요소를 지원하는 경우 실제로는 불가능합니다. 예를 들어, 헝가리 로케일에서는 on과 일치 하지만 또한 일치하므로 거기 에서 찾을 수 있습니다. will match on 그러나 또한 일치합니다 .[a-z][^a-z][a-z]dszdsz[a-z]{0,21}dszxxxyyyxxxyyyxxxyyyx[a-z]{22}

다중 문자 조합 요소가 없는 로케일의 경우 다음을 수행할 수 있습니다.

grep  '^[^a-z]*\([a-z]\{1,21\}[^a-z]\{1,\}\)*[a-z]\{0,21\}$'

grep이제 몇 가지 옵션과 함께 고급 정규 구문을 지원하는 구현 도 있습니다.부정적인운영자.

예를 들어, GNU 또는 ast-open 구현은 옵션이 grep있는 perl 유사(GNU grep의 libpcre, ast-open 자체 ast-open grep 구현) 정규식을 지원합니다.-P(?!pattern) 부정적인 예측 연산자.

(?!pattern)패턴이 거기에서 일치하지 않으면 대상 문자열의 어느 지점에서든 너비가 0인 일치가 이루어집니다. 따라서 다음을 사용할 수 있습니다.

 grep -P '^(?!.*[a-z]{22})'

뒤에 문자 수가 없고 22 [a-z]초가 없는 경우 줄의 시작 부분과 일치합니다. 그러나 PCRE(ast-open이 아님)에서는 [a-z]로케일에 관계없이 abcdefghijklmnopqrstuvwxyz만 일치합니다.

ast-open에는 -X그들이 말하는 옵션 도 있습니다향상된 정규 표현식. 이러한 향상된 정규 표현식에는 !사물을 부정하는 연산자가 있습니다. (빈 문자열 포함)을 제외한 모든 항목 x!과 일치합니다 .x

따라서 ast-open을 사용하면 grep다음 작업도 수행할 수 있습니다.

grep -X '^(.*[a-z]{22}.*)!$'

답변2

  • grep '[^a-z]\{22\}' /usr/share/dict/words

    /usr/share/dict/words소문자가 아닌 22자 문자열을 포함 하는 파일의 행을 찾습니다 . 파일에는 그러한 줄이 포함되어 있지 않을 가능성이 높습니다. (이 파일에 문자가 아닌 문자열이 22개 포함된 이유는 무엇입니까?)

  • grep -v '[a-z]\{22\}' /usr/share/dict/words

    22자 문자열을 포함하지 않는 줄을 찾습니다. 그러한 줄이 많이 있을 수 있습니다. (대부분의 단어가 22자 미만이기 때문입니다.)

관련 정보