CI066 - Oficina de Programação
Notas de Aula # 07

Prof. Armando Luiz N. Delgado

1 Expressões Regulares Básicas: grep(1)

Uma EXPRESSÃO REGULAR é uma forma compacta de especificar um padrão genérico de caracteres. Existem muitos filtros em UNIX, tais como grep(1), sed(1), awk(1) e vi(1) que usam tanto padrões exatos quanto expressões regulares.

Por exemplo, pode-se usar grep(1) para encontrar em um arquivo por todas as linhas que tenham a letra ``H'', seguida de um número qualquer de letras minúsculas, seguida da letra ``m''.

EXPRESSÕES REGULARES são parte integrante de sistemas UNIX e é EXTREMAMENTE IMPORTANTE aprender como usá-las.

Dentro de uma expressão regular, certos símbolos tem um significado especial, conforme mostrado na tabela 1. Mais símbolos com siginificado especial podem ser encontrado na seção REGULAR EXPRESSIONS no manual on-line de grep(1).


Tabela 1: Sumário de símbolos usados em Expressões Regulares
Símbolo Significado
$\cdot$ qualquer caracter simples, exceto quebra de linha (newline)
$\ast$ zero ou mais ocorrências do caracter precedente
^ início de uma linha
$ final de uma linha
$\backslash<$ início de uma palavra
$\backslash>$ final de uma palavra
$[$   $]$ um, e apenas um dos caracteres indicados pelos colchetes
$[$^   $]$ quaisquer caracteres que não estejam entre os indicados pelos colchetes
$\backslash$ toma o caracter seguinte literalmente
$[[$:alnum:$]]$ $[$0-9A-Za-z$]$
$[[$:alpha:$]]$ $[$A-Za-z$]$
$[[$:digit:$]]$ $[$0-9$]$
$[$a-d$]$ $[$abcd$]$
$[$a-dP-T$]$ $[$abcdPQRST$]$
$[$$]$a^$[$-$]$ um dos caracteres: a, ^, ], [ ou -. O símbolo ^ perde seu significado especial se não está no início da expressão entre colchetes. O símbolo - perde seu significado especial se é o último caracter da expressão entre colchetes. O símbolo ] perde seu significado se é o primeiro caracter da expressão entre colchetes.


2 Expressões Regulares Extendidas: egrep(1)

egrep(1) é um outro comando bastante usado no processamento de textos em UNIX.

egrep(1) é uma forma alternativa de grep(1) que utiliza EXPRESSÕES REGULARES EXTENDIDAS (ERE's), em contraponto com EXPRESSÕES REGULARES BÁSICAS (BRE's) usadas por grep(1).

Dentro de uma ERE, certos símbolos tem um significado especial, conforme mostrado na tabela 2. Mais símbolos com siginificado especial podem ser encontrados na seção REGULAR EXPRESSIONS no manual on-line de grep(1)/egrep(1).


Tabela 2: Sumário de símbolos usados em Expressões Regulares Extendidas
Símbolo Significado
$\ast$ zero ou mais ocorrências do elemento precedente
$+$ um ou mais ocorrências do elemento precedente
? elemento precedente é opcional, isto é, pode não ocorrer ou ocorrer apenas uma vez
{n} o elemento precedente ocorre exatamente n vezes
{n,} o elemento precedente ocorre n ou mais vezes
{n,m} o elemento precedente ocorre no mínimo n vezes e no máximo m vezes.
 |  combina 2 ERE's. A RE resultante é verdadeira para qualquer string que corresponda a uma das sub-expressões
(   ) agrupa RE's para forçar precedência entre operadores ou para definir um elemento mais complexo que um caracter, sobre o qual pode ser aplicado algum dos operadores previamente definidos.


OBSERVAÇÕES:

3 Exemplos

  1. Considere o texto abaixo, parte do conteúdo do arquivo ~ci066/Arquivos/da_janela.txt:

    Eu vi que havia um pinheiro
    entre a janela e o mar: por quanto tempo o dinheiro
    iria isto deixar?
    Pinheiro, sóbrio pinheiro,
    é tempo de navegar.
    
    Balança as folhas, sacode
    teu porte esguio, natural,
    presta atenção para o mote
    da destruição geral;
    balança que ainda podes
    do vento colher o sal.
    
    Espalha o perfume doce
    da terra de onde tu vens,
    como se ainda fosses
    senhor dos ares que tens,
    mas reconhece, acabou-se
    a era dos três vintens.
    
    Vintens
    O que são míseros vintens.
    Que olhar mais ganancioso.
    Quisera que desse moedas em um pinheirozito.
    vintens, nada mais que míseros vintens
    Prefiro dar uma olhada
    Nas frondosas galhadas.
    

    1. Mostre as linhas que contenham o string vintens.

      ci066@dupond:~egrep   vintens  ~ci066/Arquivos/da_janela.txt
      a era dos três vintens.
      O que são míseros vintens.
      vintens, nada mais que míseros vintens
      ci066@dupond:~egrep   -i vintens  ~ci066/Arquivos/da_janela.txt
      a era dos três vintens.
      Vintens
      O que são míseros vintens.
      vintens, nada mais que míseros vintens

    2. Mostre as linhas que contenham o string nheiro.

      ci066@dupond:~egrep   nheiro  ~ci066/Arquivos/da_janela.txt
      Eu vi que havia um pinheiro
      entre a janela e o mar: por quanto tempo o dinheiro
      Pinheiro, sóbrio pinheiro,
      ci066@dupond:~ 

    3. Mostre as linhas que contenham o string lha.

      ci066@dupond:~egrep   'lha'  ~ci066/Arquivos/da_janela.txt
      Balança as folhas, sacode
      Espalha o perfume doce
      Prefiro dar uma olhada
      Nas frondosas galhadas.
      ci066@dupond:~ 

    4. Mostre as linhas que contenham palavras TERMINADAS em lha ou lhas.

      ci066@dupond:~egrep   'lha$\backslash>$~ci066/Arquivos/da_janela.txt
      Espalha o perfume doce
      ci066@dupond:~ 
      ci066@dupond:~egrep   'lha.$\backslash>$~ci066/Arquivos/da_janela.txt
      Balança as folhas, sacode
      Que olhar mais ganancioso.
      ci066@dupond:~egrep   'lha.?'  ~ci066/Arquivos/da_janela.txt
      Balança as folhas, sacode
      Espalha o perfume doce
      Que olhar mais ganancioso.
      Prefiro dar uma olhada
      Nas frondosas galhadas.
      ci066@dupond:~egrep   'lhas*$\backslash>$~ci066/Arquivos/da_janela.txt
      Balança as folhas, sacode
      Espalha o perfume doce
      ci066@dupond:~egrep   'lhas?$\backslash>$~ci066/Arquivos/da_janela.txt
      Balança as folhas, sacode
      Espalha o perfume doce

    5. Mostre as linhas que contenham as palavras pinheiro ou Pinheiro.

      ci066@dupond:~egrep   '$\backslash<$[Pp]inheiro$\backslash>$~ci066/Arquivos/da_janela.txt
      Eu vi que havia um pinheiro
      Pinheiro, sóbrio pinheiro,

    6. Mostre as linhas que comecem com Balança.

      ci066@dupond:~egrep   '^Balança'  ~ci066/Arquivos/da_janela.txt
      Balança as folhas, sacode

    7. Mostre as linhas que terminem com ode ou odes.

      ci066@dupond:~egrep   'odes?$'  ~ci066/Arquivos/da_janela.txt
      Balança as folhas, sacode
      balança que ainda podes

    8. Mostre as linhas que terminem com ens.

      ci066@dupond:~egrep   'ens[,.]*$'  ~ci066/Arquivos/da_janela.txt
      da terra de onde tu vens,
      senhor dos ares que tens,
      a era dos três vintens.
      Vintens
      O que são míseros vintens.
      vintens, nada mais que miseros vintens

    9. Mostre as linhas que tenham APENAS o string vintens.

      ci066@dupond:~egrep   -i   '^vintens$'  ~ci066/Arquivos/da_janela.txt
      Vintens

      OBS.: A expressão regular acima seleciona linhas que tenham APENAS o string vintens. A linha vintens, nada mais que míseros vintens NÃO SERÁ selecionada pelo comando.

      O motivo é que grep(1) procura por uma seqüência de caracteres que coincida com o padrão indicado na expressão regular. A expressão '^vintens$' diz que a sequência de caracteres a ser encontrada (vintens) deve ser precedida de início de linha e sucedida por um final de linha.

      Na linha mencionada, a primeira ocorrência de vintens é precedida por início de linha, mas não é sucedida por final de linha, portanto não corresponde à expressão regular. Da mesma forma a segunda ocorrência de vintens é sucedida por fim de linha, mas não é precedida por um início de linha e também não corresponde à expressão regular.

      Na verdade, temos 2 ocorrências da palavra vintens na linha, mas são 2 strings distintos. A lógica de processamento de grep(1) não é visual ou semântica. Este comando processa cada linha como uma seqüência de caracteres e procura sequencialmente na linha pelo padrão indicado na expressão regular.

  2. Encontrar linhas em ~/texto.lst que tenham palavras começadas por H seguida 3 letras ou mais.

    ci066@dupond:~egrep   '$\backslash<$H[a-zA-Z][a-zA-Z][a-zA-Z][a-zA-Z]*'  ~/texto.lst
    ...
    ci066@dupond:~egrep   '$\backslash<$H[a-zA-Z][a-zA-Z][a-zA-Z]+'  ~/texto.lst
    ...
    ci066@dupond:~egrep   '$\backslash<$H[a-zA-Z]{3,}'  ~/texto.lst
    ...

  3. Encontrar linhas do arquivo ~/senhas que tenham zero ou mais caracteres entre :.

    ci066@dupond:~egrep   ':.*:'  ~/senhas
    ...

  4. Procure por redirecionamentos de saída ou entrada em seu arquivo ~/.bashrc

    ci066@dupond:~egrep   '>'  ~/.bashrc
    mostra apenas linhas com redirecionamento de saída $>$
    ci066@dupond:~egrep   '$>$  | $<$~/.bashrc

  5. Procure em ~ci066/LabNum7/words por palavras que tenham as letras a, e, i, o, u, nesta ordem. Elas não precisam estar adjacentes, mas devem estar nesta ordem.

    ci066@dupond:~egrep   '[^eiou]*a[^iou]*e[^aou]*i[^aeu]*o[^aei]*u'  ~ci066/LabNum7/words
    ....
    ci066@dupond:~egrep   '[^eiou]*a[^iou]*e[^ou]*i[^u]*o[a-zA-Z]*u'  ~ci066/LabNum7/words
    ....



Armando Luiz Nicolini Delgado
2008-07-10