Você está na página 1de 26

Incrementando o Shell

com Expressões Regulares


Rudson Ribeiro Alves - UVV
rudsonalves@yahoo.com.br
Incrementando o Shell com ERs

O que são Expressões Regulares (ERs ou regexes)?


“ER é uma composição de símbolos, caracteres com funções especiais, que,
agrupados entre si e com caracteres literais, formam uma seqüência, uma
expressão. Essa expressão é interpretada como uma regra, que indicará sucesso
se uma entrada de dados qualquer obedecer exatamente a todas as suas
condições.”
Aurélio Marinho Jargas -http://guia-er.sourceforge.net/

Senta que lá vem a História...


Em meados de 1950, o matemático Stephen Kleene descreveu um modelo
neural utilizando uma notação matemática chamada de “regular sets”.
Em dezembro de 1967, Ken Thompson transferiu essa notação para um editor
chamado QED, e para o editor de Unix ed.

Em meados de 1970, os “regular sets” evoluíram para as “Experssões Regulares”,


como as conhecemos hoje, com a criação do comando grep.

Atualmente ERs são empregadas em vários comandos, linguagens e editores:


ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find...
Incrementando o Shell com ERs

Não confunda Metacaracteres com Curingas!


Curingas são utilizados para expressar conjuntos de arquivos
na linha de comando:
● *.txt – todos os arquivos terminados com .txt

● arquivo-??.txt – dois caracteres qualquer após o hífen

● arquivo.{txt,html} – terminação txt ou html

Apresentação
✔Bibliografia
✔Comando grep, sed e tr

✔ Conhecendo os metacaracteres
Incrementando o Shell com ERs

Bibliografia:
➢ Comando man do sistema GNU/Linux (grep, sed, tr, ...)
➢ Aurélio Marinho Jargas (o verde: http://guia-

er.sourceforge.net/
➢ http://en.wikipedia.org/wiki/Regular_expression

Esta apresentação é baseada no material de ERs do


Aurélio Marinho Jargas:

http://aurelio.net/er/apostila-conhecendo-regex.pdf
Incrementando o Shell com ERs

Comando grep:
grep, egrep, fgrep – imprime linhas que casão com uma
máscara.

grep [opções] MÁSCARA [arquivo]

Exemplos:

$ grep 'root' /etc/passwd


- imprime as linhas de /etc/passwd que contêm a palavra root

$ grep -v 'root' /etc/passwd


- imprime as linhas de /etc/passwd que não contêm a palavra root

$ grep -l 'wireless' /usr/src/linux/Documentation/*


Imprime os arquivos do diretório /usr/src/linux/Documentation/ e
subdiretórios, que possuam a palavra 'wireless'
Incrementando o Shell com ERs

Comando sed
sed - editor de linha de comando para filtrar e modificar um
texto.

sed [opções] 'comandos' [arquivo]

Exemplos:

$ sed '/root/ d' /etc/passwd


- apaga as linhas que possuem a palavra root

$ sed '5,10 d' /etc/passwd


- remove as linhas de 5 a 10 do arquivo /etc/passwd

$ sed 's/root/ROOT/g' /etc/group


- substitui todas as ocorrências de root por ROOT
Incrementando o Shell com ERs

Comando tr
tr - translada ou troca caracteres

tr [opções] conjunto1 [conjunto2]

Exemplos:

$ cat /etc/group | tr -d “:”


- remove todos os caracteres “:” de /etc/group

$ echo -e “[group]\t[pass]\t[gid]\t[users]”; cat /etc/group | tr “:” “\t”


- substitui todos os caracteres “:” por um tab
Incrementando o Shell com ERs

Metacaracteres
Metacaracteres são caracteres com funções específicas, que
informam padrões e posições impossíveis de serem
especificadas com caracteres normais.

Exemplo:
- todas as linhas iniciadas pelos caracteres “a”,”b”,”c” e “d”, e
que terminam com “1”
- todas as linhas que possuam três números em seqüência
- todos as linhas que possuem um padrão de data
(dd/mm/aaaa)
- ...
Incrementando o Shell com ERs

O metacaracter circunflexo ^
O ^, representa o início de uma linha. Podemos usá-lo para
encontrar todas as linhas iniciadas por uma seqüência de
caracteres específicas.

Exemplos:
$ grep '^root' /etc/passwd
- filtra todas as linhas iniciadas pela palavra 'root'
$ grep '^a' /etc/passwd
- filtra todas as linhas iniciadas pelo caracter 'a'
$ sed '/^s/ d' /etc/group
- remove todas as linhas iniciadas pelo caracter 's'
$ grep -v '^s' /etc/group
- o mesmo que o sed acima
Incrementando o Shell com ERs

O metacaracter cifrão $
O $, representa um fim de uma linha. Podemos usá-lo para
encontrar todas as linhas terminadas por uma seqüência de
caracteres específicas.

Exemplos:
$ grep 'root$' /etc/group
- filtra todas as linhas terminadas pela palavra 'root'
$ grep 'bash$' /etc/passwd
- filtra todos os usuários que utilizam o bash como shell padrão

Dica do Aurélio:
ER para encontrar linhas em branco: ^$
sed '/^$/ d' /etc/profile
- remove linhas em branco do arquivo /etc/profile
Incrementando o Shell com ERs

O metacaracter de lista []
Os [] permitem limitar um conjunto de caracteres a ocupar
uma dada posição no texto.
Exemplos:
$ grep '^[aeiou]' /etc/group
- filtra todos os grupos com nome iniciado pelas vogais
$ grep '^[bcdfghjklmnpqrstvxywz]' /etc/passwd
- filtra todas os usuários cujo o nome inicia por uma consoante
$ grep '[0123456789][0123456789][0123456789]' /etc/group
- filtra todas as linhas que possuam três números em seqüência
$ sed
'y/abcdefghijklmnopqrstuvxywz/ABCDEFGHIJKLMNOPQRDTUVXYWZ/' /
etc/group
- transforma o conteúdo do /etc/group em caixa alta
Incrementando o Shell com ERs

O metacaracter hífen, para intervalo de listas [-]


Para lista seqüênciais como 0123456789, abcd...z é possível
utilizar o meta caracter -, para simbolizar a seqüência:

Exemplos:

$ grep '[0-9][0-9][0-9]' /etc/group


- filtra todas as linhas que possuam três números em seqüência
$ sed 'y/[a-z]/[A-Z]/' /etc/group
- a opção y do sed considera tudo como caracter. Não irá funcionar
como desejado

$ cat /etc/group | tr [a-z] [A-Z]


- transforma o conteúdo do /etc/group em caixa alta, com mais
elegância
Incrementando o Shell com ERs

Metacaracter ponto .
O . é um metacaracter que representa “qualquer” caracter em
uma dada posição.

Exemplos:

$ grep '^.[aeiou]' /etc/group


- filtra todas as linhas que iniciam com qualquer caracter,
seguido de uma vogal
$ grep '^...................$' /etc/passwd
- filtra todas as linhas que possuem 19 caracteres

E se quiser as linhas com 41 caracteres, terá que usar 41 pontos!


Incrementando o Shell com ERs

Metacaracter chaves {}
As {} serve para indicar a quantidade de repetições de um
caracter ou metacaracter

Exemplos:

$ grep '^.\{41\}$' /etc/passwd


- filtra todas as linhas que possuem 41 caracteres. Observe que
as barras reverssas, “\”, são necessários para escapar as chaves
no grep. É sugerido utilizar o egrep no lugar do grep.

$ egrep '^.{41}$' /etc/passwd


- mesmo comando acima, porem mais limpo

$ egrep '^.{20,40}$' /etc/passwd


- filtra as linhas com 20 a 40 caracteres
Incrementando o Shell com ERs

Metacaracter chaves {}
Mais exemplos:
$ egrep '^.{20,}' /etc/passwd
- filtra as linhas com 20 ou mais caracteres.
$ egrep '^.{,27}$' /etc/passwd
- filtra as linhas com menos de 27 caracteres

Algumas abreviações de repetição:


Meta Equivalência Descrição
? {0,1} pode aparecer uma vez ou não
* {0,} pode aparecer quauqer quantidade, inclusive nenhuma
+ {1,} aparecer uma vez ou mais
$ egrep '^.+$' /etc/profile
- filtra as linhas com 1 ou mais caracteres, ou seja, linhas não
vazias
Incrementando o Shell com ERs

Metacaracter .*
O metacaracter .* equivale ao curinga * utilizado no comando
ls, ou seja, ele representa qualquer caracter em qualquer
quantidade.
$ egrep '^[aeiou].*bash$' /etc/passwd
- filtra todas as linhas iniciadas com uma vogal e terminadas
com a palavra “bash”

Separar NOME, VERSÃO e EXTENSÃO do nome de uma fonte:


Exemplo: lame-2.93.tar.gz
sed => s/(nome)-(versão).(extensão)$/CAMPO
CAMPO - 1 - nome, 2 - versão e 3 para extensão
s/(.*)-(.*).(.* . .*)/... => escapar () e . (ponto mesmo)
sed 's/\(.*\)-\(.*\)\.\(.*\..*\)/\1 2 ou 3/' ou
sed -r 's/(.*)-(.*)\.(.*\..*)/\1 2 ou 3/' sem escapar os ()
Incrementando o Shell com ERs

Resolvendo:
$ SOURCE=”lame-2.93.tar.gz”
$ echo $SOURCE | sed -r 's/(.*)-(.*)\.(.*\..*)/\1/' #nome
lame
$ echo $SOURCE | sed -r 's/(.*)-(.*)\.(.*\..*)/\2/' # versão
2.93
$ echo $SOURCE | sed -r 's/(.*)-(.*)\.(.*\..*)/\3/' # extensão
tar.gz
Incrementando o Shell com ERs

Metacaracter ou (|)
As listas, [], trabalham apenas com caracteres, mas em outras
ocasiões é necessário procurar por palavras alternativas. Para
isto de usa o ou lógico |

$ egrep '^(root|adm|lp):' /etc/passwd


- filtra apenas as linhas iniciadas com root, adm ou lp

Metacaracter de negação de lista [^]


Para se negar uma lista, basta colocar o circunflexo a frente
dos caracteres negados
$ egrep '^[^aeiou]' /etc/passwd
- filtra as linhas iniciadas com consoantes, o mesmo que o
comando:
$ egrep '^[bcdfghjklmnpqrstvxwyz]' /etc/passwd
Incrementando o Shell com ERs

Quando escapar?
Dependendo do aplicativo, as ERs podem ter algumas
variações. O Aurélio montou a tabela abaixo para saber
quando escapar ou não:

Programa Opção mais chaves borda ou grupo


awk ? + - - | ()
egrep ? + {,} \b | ()
grep \? \+ \{,\} \b \| \(\)
emacs ? + - \b \| \(\)
find ? + - \b \| \(\)
gawk ? + {,} \<\> | ()
sed* \? \+ \{,\} \<\> \| \(\)
vim \= \+ \{,\} \<\> \| \(\)
* o sed possui a opção -r que estende o uso de ERs, evitando a maioria dos escapes
Incrementando o Shell com ERs

Resumo dos metacaracteres

Meta Posicionamento
^ início da linha
$ final da linha
Lista
[abc] casa com os caracteres a, b e c
[a-c] casa com os caracteres a, b e c
[^abd] não casa com os caracteres a, b e d
(um|dois) casa com as palavras um e dois
Repetições
a{2} casa com a letra “a” duas vezes
a{2,5} casa com a letra “a” duas a cinco vezes
a{2,} casa com a letra “a” duas vezes ou mais
a? casa com “a” letra a zero vezes ou uma
a* casa com a letra “a” zeros vezes ou mais
a+ casa com a letra “a” uma vez ou mais
Curingas
. casa com qualquer caracter uma vez
.* casa com qualquer caracter várias vezes
Incrementando o Shell com ERs

Hora da diversão: Alguns desafios


Desafio 1: Remover as tags HTML de Programacao.html,
sem remover <> (diferente).

Sugestão: sed -r 's/padrão/substituto/g'

Solução com “sed -r” ou escapar +, \+

$ sed -r 's/<[^>]+>//g' Programacao.html


Incrementando o Shell com ERs

Desafio 2: Validar datas da lista data.txt


O Arquivo data.txt:
13/05/2004 45/04/2003 22/06/1967
02/08/1995 17/09/1068 22/27/1990
12/02/2405 123/02/2000 12/124/2005
06/04/27 13-05-2004 45-04-2003
22-06-1967 17-09-1068 02-08-1995
22-27-1990 12-02-2405 123-02-2000
12-124-2005 06-04-27 13.05.2004
45.04.2003 22.06.1967 17.09.1068
22.27.1990 02.08.1995 12.02.2405
05..02.2000 12.124.2005 06.04.27

Solução da validação de datas com egrep ou escapar os \(\)

'^(0[0-9]|[12][0-9]|3[01])[-/.](0[1-9]|1[12])[-/.](19|20)[0-9]
[0-9]'
Incrementando o Shell com ERs

Desafio 3: Validar emails da lista emails.txt


ze
ze@mane
ze@mane.com
ze@mane.com.br
ze@mane.br
ze.mane@mane
ze.mane@mane.co.uk
ze@mane.com.com
ze@
ze_mane@mane.com
ze-man@mane.com.br
@ze.com
ze-cezar_mane@antena.com.oque
Incrementando o Shell com ERs

Solução:
Expressão Regular: [a-zA-Z_-.]+@[0-9a-zA-Z.-]+\.[a-z]{2,3}$

$ egrep '[a-zA-Z_-.]+@[0-9a-zA-Z.-]+\.[a-z]{2,3}$' emails.txt


ze@mane.com
ze@mane.com.br
ze@mane.br
ze.mane@mane.co.uk
ze@mane.com.com
ze_mane@mane.com
ze-man@mane.com.br
Incrementando o Shell com ERs

Diversão garantida com sed:


tenho um arquivo texto com 15000 linhas com o seguinte formato:
$ cat a.txt
006528SL757317280BR12/09/200513/01/200500000201134702240593000000602005011304
006528SL757317259BR12/09/200513/01/200500000201134702240593000000612005011304
006528SL757317245BR12/09/200513/01/200500000201134702240593000000622005011304
006528SL757317188BR12/09/200513/01/200500000201134702240593000000632005011304

e quero formatar esse arquivo para dar um LOAD DATA LOCAL INFILE no mysql, para tanto
quero inserir um tab como separador de campos para separá-los na forma

006528 SL757317280BR 12/09/2005 13/01/2005 000002011347 02240593000000602005011304

sed -r 's/^(.{6})(.{13})(.{10})(.{10})(.{12})(.*)$/ \1\t\2\t\3\t\4\t\5\t\6/' a.txt

006528 SL757317280BR 12/09/2005 13/01/2005 000002011347 02240593000000602005011304


006528 SL757317259BR 12/09/2005 13/01/2005 000002011347 02240593000000612005011304
006528 SL757317245BR 12/09/2005 13/01/2005 000002011347 02240593000000622005011304
006528 SL757317188BR 12/09/2005 13/01/2005 000002011347 02240593000000632005011304
Incrementando o Shell com ERs

FIM

Você também pode gostar