Nenhuma saída para $ grep '[^ a-z] \ {22 \}' / usr / share / dict / words

0

Depois de executar

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

a saída é

counterrevolutionaries
electroencephalographs

mas durante a execução

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

não há saída.

Eu esperava que ele gerasse resultados semelhantes aos de

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

Minha pergunta é o que está errado e por quê?

    
por Neo_Returns 24.05.2018 / 14:56

3 respostas

4

[specification] corresponde a um elemento de intercalação (pode ser um caractere ou sequência de caracteres conforme definido no algoritmo de intercalação da localidade (por exemplo, em locais húngaros em sistemas GNU, dzs é um elemento de intercalação que classifica em algum lugar entre d e e )) no conjunto especificado .

Essa especificação pode incluir

  • varia como a-z (ou [.dzs.]-z ) para agrupar elementos que agrupam entre a e z (observe que geralmente inclui abcdefghijklmnoprstuvwxyz, mas na maioria das localidades, inclui muito mais). Além disso, como POSIX não é especificado para locais diferentes dos locais POSIX, o quanto esses intervalos são baseados na ordem de agrupamento varia significativamente entre as implementações.
  • caracteres individuais ou elementos de agrupamento ( x , [.dsz.] )
  • Classes de caracteres POSIX [:alpha:] , [:digit:]
  • classes equivalentes como [=e=] para todos os elementos de intercalação que possuem o mesmo peso de classificação primário que e (pode incluir itens como é )

Portanto, por exemplo, [acd[=e=]h-k[:digit:][.dzs.]] corresponde a um elemento de intercalação, desde que seja a , c , d , dzs ou equivalente a e ou agrupamentos entre h e k ou é classificado como dígito .

E se a especificação começar com ^ , ela ainda corresponderá a um elemento de intercalação, mas com o conjunto complementado. Isso é qualquer elemento de agrupamento, mas os especificados.

Portanto, [^a-z] corresponde a qualquer elemento de intercalação que não agrupe entre a e z . Por exemplo, provavelmente corresponderia a 1 e , possivelmente a X ou DSZ , dependendo da localidade e da implementação grep , mas não da a , x nor z e provavelmente não em é .

Portanto, grep '[^a-z]\{22\}' corresponde a linhas que contêm uma sequência de 22 elementos de comparação que agrupam antes de a ou depois de z .

Enquanto grep -v '[a-z]\{22\}' corresponde a linhas que não contêm uma sequência de 22 elementos de agrupamento, agrupados entre a e z .

A correspondência do mesmo sem -v é quase impossível de implementar, você precisaria corresponder em linhas que não contenham mais de 21 [a-z] elementos de intercalação entre dois [^a-z] elemento. Mas se a localidade suportar elementos de agrupamento de vários caracteres, isso não é realmente possível. Por exemplo, nessas localidades húngaras, [a-z] corresponde a dsz , mas também a d , s e z , então você verá que, [a-z]{0,21} corresponderá a dszxxxyyyxxxyyyxxxyyyx , mas também [a-z]{22} .

Para locais que não possuem elementos de classificação de vários caracteres, você pode fazer algo como:

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

Agora, também há algumas implementações grep que suportam sintaxes regulares mais avançadas com opções que possuem algum operador negação .

Por exemplo, a implementação GNU ou ast-open das expressões regulares grep suportam perl-like (usando libpcre no GNU grep, própria implementação do ast-open para ast-open grep) com a opção -P que tem um (?!pattern) operador de look-ahead negativo .

(?!pattern) corresponde à largura zero em qualquer ponto da cadeia de assunto, desde que o padrão não corresponda a partir de lá. Então, pode-se usar:

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

para corresponder no início da linha, desde que não seja seguido por nenhum número de caracteres e 22 [a-z] s. No entanto, observe que no PCRE (não em ast-open), [a-z] corresponde apenas a abcdefghijklmnopqrstuvwxyz, independentemente da localidade.

o ast-open também usa uma opção -X para o que eles chamam de expressões regulares aumentadas . Esses regex aumentados têm um operador ! que nega as coisas. x! corresponderia a algo diferente de x (incluindo a string vazia).

Portanto, com ast-open grep , você também pode:

grep -X '^(.*[a-z]{22}.*)!$'
    
por 24.05.2018 / 15:31
3
  • grep '[^a-z]\{22\}' /usr/share/dict/words

    Procura por linhas no arquivo /usr/share/dict/words que contenha uma sequência de 22 caracteres que não sejam letras minúsculas. É muito provável que o arquivo não contenha essa linha. (Por que esse arquivo contém strings de 22 não-letras?)

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

    Procura linhas que não contenham cadeias de 22 letras. Provavelmente haverá muitas dessas linhas. (Porque a maioria das palavras tem menos de 22 letras.)

por 24.05.2018 / 15:23
-1

Eu acho que você estraga suas saídas.

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

corresponde a qualquer sequência de 23 letras minúsculas; os dois counterrevolutionaries e electroencephalographs têm 22

Então, provavelmente,

counterrevolutionaries
electroencephalographs

foi a saída de grep '[a-z]\{22\}' /usr/share/dict/words .

Por outro lado, grep -v '[^a-z]\{22\}' /usr/share/dict/words corresponde a qualquer sequência de caracteres diferente de 22 letras não minúsculas seguidas ; assim, por exemplo, qualquer sequência de caracteres com menos de 22 caracteres, corresponde (quase todas as palavras); Além disso, note que qualquer seqüência de 22 caracteres com pelo menos um caractere minúsculo, corresponde também.

    
por 24.05.2018 / 15:25