Expressão regular para encontrar caracteres duplos no Bash


10

Estou procurando uma expressão regular que encontre todas as ocorrências de caracteres duplos em um texto, uma listagem etc. na linha de comando (Bash).

Principal Pergunta : Existe uma maneira simples de olhar para seqüências como aa, ll, ttttt, etc., onde se define uma expressão regular que procura n ocorrências da mesma personagem com? O que estou procurando é conseguir isso em um nível muito, muito básico. Na linha de comando. Em um shell Linux.

Depois de algumas pesquisas, cheguei às seguintes respostas - e perguntas resultantes delas; assim, elas me deram uma dica de onde a solução poderia estar. Mas:

a) (e) grep e a barra invertida

  • grep 'a\{2\}' procura aa
  • egrep'a{2}' procura aa

Pergunta: A necessidade de definir barras invertidas está realmente vinculada ao comando que eu uso? Nesse caso, alguém pode me dar uma dica do que mais deve ser levado em consideração ao usar o (e) grep aqui?

b) Encontrei esta resposta aqui para a minha pergunta, embora não seja exatamente o que eu estava procurando:

grep -E '(.)\1' filenameprocura entradas com o mesmo caractere aparecendo mais de uma vez, mas não pergunta com que frequência . Isso é próximo do que estou procurando, mas ainda quero definir várias repetições.

Provavelmente devo dividir isso em duas ou mais perguntas, mas não quero inundar este site incrível aqui.

PS: Outra pergunta, possivelmente off topic, mas: é in, inside, atou on the shell. E está on the command linecorreto?

Respostas:


8

São realmente duas perguntas e deveriam ter sido divididas. Mas como as respostas são relativamente simples, vou colocá-las aqui. Essas respostas são grepespecificamente para o GNU .

a) egrepé o mesmo que grep -E. Ambos indicam que "Expressões regulares estendidas" devem ser usadas em vez das grepexpressões regulares padrão. greprequer as barras invertidas para expressões regulares comuns.

Na manpágina:

Expressões regulares básicas versus estendidas

Nas expressões regulares básicas, os meta-caracteres ? , + , { , | , ( , e ) perdem seu significado especial; em vez disso, use as versões com barra invertida \? , \ + , \ { , \ | , \ ( , e \) .

Veja a manpágina para detalhes adicionais sobre convenções históricas e portabilidade.

b) Use egrep '(.)\1{N}'e substitua Npelo número de caracteres que você deseja substituir menos um (já que o ponto corresponde ao primeiro). Portanto, se você quiser combinar um personagem repetido quatro vezes, use egrep '(.)\1{3}'.


Ao ler a página de manual, devo ter realmente interpretado mal ou mal a parte que você apontou. Quando eu trabalhei com alguns tutoriais de expressão regular, não havia pistas de tal comportamento. Eu pensei que Expressão Regular significa algo em um nível tão básico que a maioria dos aplicativos está trabalhando com o mesmo conjunto de símbolos. Mais uma vez, eu estava provado errado. Obrigado pela ajuda! Isso realmente me ajudou.
erch

Também é uma leitura bastante confusa " sempre use a barra invertida para pegar o significado especial de caracteres como., +, Etc. " e depois descobrir que aparentemente o oposto é a regra com o comando mais básico.
erch

@ cellar.dweller É confuso! Muito do raciocínio é histórico. Eu estou mais familiarizado com o formulário Estendido, por isso tenho o hábito de sempre usar apenas egrepse precisar de expressões regulares (em vez de apenas uma correspondência simples de seqüências de caracteres) para não precisar me preocupar em lembrar as diferenças entre grepos dois tipos de expressões regulares.
depquid

4
Observe que os EREs padrão não suportam referências posteriores, enquanto os BREs padrão suportam. Então grep '\(.\)\1\{3\}'é padrão, grep -E '(.)\1{3}'não é.
Stéphane Chazelas

7

Isso procuraria 2 ou mais ocorrências do mesmo caractere:

grep -E '(.)\1+' file

Se o seu awk tiver a opção -o, ele será impresso a cada partida em uma nova linha.

grep -Eo '(.)\1+' file

Para encontrar correspondências com exatamente 3 correspondências:

grep -E '(.)\1{2}' file

Ou 3 ou mais:

grep -E '(.)\1{2,}' file

etc ..


editar

Na verdade, @stephane_chazelas está certa sobre as referências anteriores e -E. Eu tinha esquecido disso. Eu tentei no BSD grep e GNU grep e funciona lá, mas não está em outros greps. Você precisaria usar uma das versões abaixo ..

Versões regulares do grep:

grep '\(.\)\1\{1,\}' file

grep -o '\(.\)\1\{1,\}' file

grep '\(.\)\1\{2\}' file

grep '\(.\)\1\{2,\}' file

A -oopção também não é o padrão grep BTW (provavelmente se o seu grep entender -o também pode fazer a referência traseira) ..


Nota : grep -E '(.)\1{2,}'arquivo e grep '\(.\)\1\{2\}'arquivo estão errados, como indicado por alexis, e devem ser ignorados.


Obrigado até agora. Mas: estou certo dizendo que sem a -Eopção grepnão faria muito? Isso explicaria bastante, por exemplo, por que perdi tanto tempo procurando onde estava errado!
erch

Sem a opção -E, você pode fazer o mesmo neste caso, mas precisaria escapar mais e não há +operador. Vou postar exemplos também.
Scrutinizer

Uma pequena correção: grep -E '(.)\1{2}'não exatamente "Encontra correspondências com exatamente 3 correspondências". Embora corresponda exatamente a três caracteres idênticos, eles podem ser incorporados em uma sequência repetida mais longa; por exemplo, ele corresponderá na sequência de 5 símbolos AAAAA. (E se houver 6 ou mais símbolos consecutivos, ele corresponderá mais de uma vez).
Alexis

Sim, você está absolutamente certo, isso não funcionar como pretendido, de fato, não é possível assim ..
Scrutinizer

3

Primeiro, obrigado a todos por seus comentários e sugestões. Acontece que eu já estava bem perto da resposta.

A questão principal era sobre:

Existe uma maneira simples de procurar n ocorrências do mesmo caractere, por exemplo aa,tttttt

Resposta curta :

Os seguintes comandos [variações de] repetirão apelo menos uma e infinitas vezes

grep 'a\{1,}

grep -E \(a\)\{1,\}

egrep a{1,}

ou, com expressões regulares GNU disponíveis grep a\+


O número de repetições é definido dentro dos colchetes, através do padrão {min,max}{n}repita exatamente as nvezes, {n,}repita pelo menos nvezes e {n,m}repita pelo menos, nmas na maioria das mvezes.

Assim, como conseqüência, levantou a questão secundária :

A necessidade de definir barras invertidas está vinculada ao comando que eu uso?

Resposta curta : Sim, o uso de barras invertidas depende se alguém usa grepou nãoegrep

  • grep: barra invertida ativa metacaracteres [usa expressões regulares básicas]
  • egrepbarra invertida de -ativa metacharacters [usos Extensão expressões regulares]

Como esta é a resposta curta, quero fornecer àqueles que tiveram problemas comparáveis. Adicionei meu resumo básico do que aparentemente alguém precisa estar ciente, trabalhando com grepe egrep.




Expressões regulares básicas, estendidas e GNU

Expressões regulares básicas

Usado em grep, ede sedcomando

Os recursos do conjunto Expressões regulares básicas são:

  • A maioria dos metacaracteres, por exemplo, ? [ . \ )etc., é ativada através de uma barra invertida. Se não houver barra invertida, elas serão consideradas como (parte do) termo de pesquisa.
  • ^ $ \<e \>são suportados sem uma barra invertida
  • Não há personagens taquigrafia [ \b, \s, etc.]

Expressões regulares básicas do GNU adicionam a esses

  • \?repetição de caracteres zero ou uma vez ( c\?partidas ce cc) e é uma alternativa para\{0,1\}
  • \+repetir um personagem pelo menos uma vez ( c\+correspondências cc, ccccccccetc.) e é uma alternativa para\{1,\}

  • \|é suportado (por exemplo grep a\|b, procurará aoub

grep -E permite que o comando use todo o conjunto de expressões regulares estendidas:


Expressões regulares estendidas [ERE]

Usado em egrep, awke emacsé o conjunto básico, além de alguns recursos.

  • Os metacaracteres são desativados através de uma barra invertida
  • Sem referências anteriores
  • mais: muitas das expressões regulares mágicas geralmente podem fazer por um

Expressões regulares do GNU Extendend

adiciona os seguintes recursos

Os dois links direcionarão um para o regular-expressions.info que, além do suporte impressionante que tenho aqui, realmente me ajudou muito.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.