grep equivalente do regex kwrite [A-Z] [A-Z] +

1

Então, eu demorei, mas finalmente aprendi a pensar em termos de expressões regulares, graças a usá-las em kwrite .

Mas ainda não sei como traduzir esse conhecimento para grep . Eu amo meu grep , quando eu sei o que estou fazendo com ele, mas o manual sempre me deu dor de cabeça.

Gostaria de combinar coisas como as seguintes linhas:

CAPITALSFOLLOWING anewline.
CAPI
TALSFOLL owing
ANEW line.

Isto é, linhas que começam com duas ou mais letras maiúsculas. Mas não consigo descobrir como.

Em kwrite , eu combinaria essas linhas usando:

\n[A-Z][A-Z]+

Mas grep ... hmm. Eu tenho a sensação de que é algo como:

me@ROOROO:~/$ grep "^[A-Z]something" filename

mas

me@ROOROO:~/$ grep "^[A-Z][A-Z]+" filename

não funciona (retorna um arquivo vazio). Uma pesquisa no google pelo termo 'grep corresponde a uma ou mais ocorrências' leva-me a acreditar que

me@ROOROO:~/$ grep "^[A-Z][A-Z]*" filename

foi a sintaxe correta. Mas, infelizmente, isso não funciona.

    
por ixtmixilix 10.02.2012 / 18:41

3 respostas

7

Você está usando a sintaxe correta em seu primeiro exemplo; o problema é + só é considerado especial ao usar expressões regulares "estendidas". A partir da página man da implementação GNU de grep :

Basic vs Extended Regular Expressions

In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, \+, \{, \|, \(, and \).

( \? , \+ e \| são extensões GNU não padrão).

Então, você precisa escapar do + (assumindo o GNU grep ou compatível):

$ grep "^[A-Z][A-Z]\+" filename

Use o equivalente \{1,\} padrão do \+ do GNU:

$ grep '^[A-Z][A-Z]\{1,\}' filename

ou até aqui:

$ grep '^[A-Z]\{2,\}' filename

Ou ative as expressões regulares estendidas, passando grep o -E sinalizador ou apenas executando egrep ( egrep é o comando que introduziu essas expressões regulares estendidas no final dos anos 70):

$ grep -E "^[A-Z][A-Z]+" filename
$ egrep "^[A-Z][A-Z]+" filename

Em qualquer caso, todos esses seriam funcionalmente equivalentes a:

$ grep '^[A-Z][A-Z]' filename

Assim, você nem precisa do operador + .

No outro exemplo, você tentou:

$ grep "^[A-Z][A-Z]*" filename

* funciona em expressões regulares básicas, mas corresponde a 0 ou mais vezes, não a 1 ou mais. A solução em sua resposta funciona porque diz "corresponde a um capital, depois a outro capital, a 0 ou mais capitais" . O método na pergunta diz "corresponde a um capital, em seguida, 1 ou mais capitais", que é o mesmo. Você também pode usar {min,max} para especificar exatamente quantos deseja e, se deixar de fora max , permite qualquer número (isso também requer expressões regulares estendidas):

$ egrep "^[A-Z]{2,}"

(como uma observação do histórico, egrep não suportou {min,max} inicialmente (e ainda não faz isso no Solaris 11 /bin/egrep ). \{min,max\} support foi adicionado a grep antes de {min,max} foi adicionado a egrep (que, no caso de egrep , quebrou a compatibilidade com versões anteriores)).

    
por 10.02.2012 / 19:12
2

Você só precisa adicionar um extra [A-Z]. Então, é

me@ROOROO:~/$ grep "^[A-Z][A-Z][A-Z]*" filename
    
por 10.02.2012 / 18:42
0

Parece que você precisa de um suporte de expressão regular de perl . Formulário man grep :

   -P, --perl-regexp
          Interpret  PATTERN  as  a Perl regular expression.  This is highly experimental
          and grep -P may warn of unimplemented features.

Então grep -P "^[A-Z][A-Z]+" poderia ser mais útil.

    
por 10.02.2012 / 19:05