Você está na página 1de 26

Incrementando o Shell

com Expresses Regulares


Rudson Ribeiro Alves - UVV
rudsonalves@yahoo.com.br

Incrementando o Shell com ERs


O que so Expresses Regulares (ERs ou regexes)?
ER uma composio de smbolos, caracteres com funes especiais, que,
agrupados entre si e com caracteres literais, formam uma seqncia, uma
expresso. Essa expresso interpretada como uma regra, que indicar sucesso
se uma entrada de dados qualquer obedecer exatamente a todas as suas
condies.
Aurlio Marinho Jargas -http://guia-er.sourceforge.net/

Senta que l vem a Histria...


Em meados de 1950, o matemtico Stephen Kleene descreveu um modelo
neural utilizando uma notao matemtica chamada de regular sets.
Em dezembro de 1967, Ken Thompson transferiu essa notao para um editor
chamado QED, e para o editor de Unix ed.
Em meados de 1970, os regular sets evoluram para as Expersses Regulares,
como as conhecemos hoje, com a criao do comando grep.
Atualmente ERs so empregadas em vrios comandos, linguagens e editores:
ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find...

Incrementando o Shell com ERs


No confunda Metacaracteres com Curingas!
Curingas so utilizados para expressar conjuntos de arquivos
na linha de comando:
*.txt todos os arquivos terminados com .txt
arquivo-??.txt dois caracteres qualquer aps o hfen
arquivo.{txt,html} terminao txt ou html

Apresentao
Bibliografia
Comando grep, sed e tr
Conhecendo os metacaracteres

Incrementando o Shell com ERs


Bibliografia:
Comando man do sistema GNU/Linux (grep, sed, tr, ...)
Aurlio Marinho Jargas (o verde: http://guiaer.sourceforge.net/
http://en.wikipedia.org/wiki/Regular_expression

Esta apresentao baseada no material de ERs do


Aurlio Marinho Jargas:
http://aurelio.net/er/apostila-conhecendo-regex.pdf

Incrementando o Shell com ERs


Comando grep:
grep, egrep, fgrep imprime linhas que caso com uma
mscara.
grep [opes] MSCARA [arquivo]
Exemplos:
$ grep 'root' /etc/passwd
- imprime as linhas de /etc/passwd que contm a palavra root
$ grep -v 'root' /etc/passwd
- imprime as linhas de /etc/passwd que no contm a palavra root
$ grep -l 'wireless' /usr/src/linux/Documentation/*
Imprime os arquivos do diretrio /usr/src/linux/Documentation/ e
subdiretrios, 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 [opes] '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 ocorrncias de root por ROOT

Incrementando o Shell com ERs


Comando tr
tr - translada ou troca caracteres
tr [opes] 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 so caracteres com funes especficas, que
informam padres e posies impossveis 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 trs nmeros em seqncia
- todos as linhas que possuem um padro de data
(dd/mm/aaaa)
- ...

Incrementando o Shell com ERs


O metacaracter circunflexo ^
O ^, representa o incio de uma linha. Podemos us-lo para
encontrar todas as linhas iniciadas por uma seqncia de
caracteres especficas.
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 cifro $
O $, representa um fim de uma linha. Podemos us-lo para
encontrar todas as linhas terminadas por uma seqncia de
caracteres especficas.
Exemplos:
$ grep 'root$' /etc/group
- filtra todas as linhas terminadas pela palavra 'root'
$ grep 'bash$' /etc/passwd
- filtra todos os usurios que utilizam o bash como shell padro
Dica do Aurlio:
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 posio no texto.
Exemplos:
$ grep '^[aeiou]' /etc/group
- filtra todos os grupos com nome iniciado pelas vogais
$ grep '^[bcdfghjklmnpqrstvxywz]' /etc/passwd
- filtra todas os usurios cujo o nome inicia por uma consoante
$ grep '[0123456789][0123456789][0123456789]' /etc/group
- filtra todas as linhas que possuam trs nmeros em seqncia
$ sed
'y/abcdefghijklmnopqrstuvxywz/ABCDEFGHIJKLMNOPQRDTUVXYWZ/' /
etc/group
- transforma o contedo do /etc/group em caixa alta

Incrementando o Shell com ERs


O metacaracter hfen, para intervalo de listas [-]
Para lista seqnciais como 0123456789, abcd...z possvel
utilizar o meta caracter -, para simbolizar a seqncia:
Exemplos:
$ grep '[0-9][0-9][0-9]' /etc/group
- filtra todas as linhas que possuam trs nmeros em seqncia
$ sed 'y/[a-z]/[A-Z]/' /etc/group
- a opo y do sed considera tudo como caracter. No ir funcionar
como desejado
$ cat /etc/group | tr [a-z] [A-Z]
- transforma o contedo do /etc/group em caixa alta, com mais
elegncia

Incrementando o Shell com ERs


Metacaracter ponto .
O . um metacaracter que representa qualquer caracter em
uma dada posio.
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 repeties de um
caracter ou metacaracter
Exemplos:
$ grep '^.\{41\}$' /etc/passwd
- filtra todas as linhas que possuem 41 caracteres. Observe que
as barras reverssas, \, so necessrios 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 abreviaes de repetio:

Meta
?
*
+

Equivalncia
{0,1}
{0,}
{1,}

Descrio
pode aparecer uma vez ou no
pode aparecer quauqer quantidade, inclusive nenhuma
aparecer uma vez ou mais

$ egrep '^.+$' /etc/profile


- filtra as linhas com 1 ou mais caracteres, ou seja, linhas no
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, VERSO e EXTENSO do nome de uma fonte:
Exemplo: lame-2.93.tar.gz
sed => s/(nome)-(verso).(extenso)$/CAMPO
CAMPO - 1 - nome, 2 - verso e 3 para extenso
s/(.*)-(.*).(.* . .*)/... => escapar () e . (ponto mesmo)
sed 's/\(.*\)-\(.*\)\.\(.*\..*\)/\1 2 ou 3/'
sed -r 's/(.*)-(.*)\.(.*\..*)/\1 2 ou 3/'

ou
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/' # verso
2.93
$ echo $SOURCE | sed -r 's/(.*)-(.*)\.(.*\..*)/\3/' # extenso
tar.gz

Incrementando o Shell com ERs


Metacaracter ou (|)
As listas, [], trabalham apenas com caracteres, mas em outras
ocasies necessrio procurar por palavras alternativas. Para
isto de usa o ou lgico |
$ egrep '^(root|adm|lp):' /etc/passwd
- filtra apenas as linhas iniciadas com root, adm ou lp

Metacaracter de negao 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
variaes. O Aurlio montou a tabela abaixo para saber
quando escapar ou no:

Programa Opo mais chaves borda


awk
?
+
egrep
?
+
{,}
\b
grep
\?
\+
\{,\}
\b
emacs
?
+
\b
find
?
+
\b
gawk
?
+
{,}
\<\>
sed*
\?
\+
\{,\} \<\>
vim
\=
\+
\{,\} \<\>

ou
|
|
\|
\|
\|
|
\|
\|

grupo
()
()
\(\)
\(\)
\(\)
()
\(\)
\(\)

* o sed possui a opo -r que estende o uso de ERs, evitando a maioria dos escapes

Incrementando o Shell com ERs


Resumo dos metacaracteres
Meta
^
$
[abc]
[a-c]
[^abd]
(um|dois)
a{2}
a{2,5}
a{2,}
a?
a*
a+
.
.*

Posicionamento
incio da linha
final da linha
Lista
casa com os caracteres a, b e c
casa com os caracteres a, b e c
no casa com os caracteres a, b e d
casa com as palavras um e dois
Repeties
casa com a letra a duas vezes
casa com a letra a duas a cinco vezes
casa com a letra a duas vezes ou mais
casa com a letra a zero vezes ou uma
casa com a letra a zeros vezes ou mais
casa com a letra a uma vez ou mais
Curingas
casa com qualquer caracter uma vez
casa com qualquer caracter vrias vezes

Incrementando o Shell com ERs


Hora da diverso: Alguns desafios
Desafio 1: Remover as tags HTML de Programacao.html,
sem remover <> (diferente).
Sugesto: sed -r 's/padro/substituto/g'

Soluo 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
02/08/1995
17/09/1068
12/02/2405
123/02/2000
06/04/27
13-05-2004
22-06-1967
17-09-1068
22-27-1990
12-02-2405
12-124-2005
06-04-27
45.04.2003
22.06.1967
22.27.1990
02.08.1995
05..02.2000
12.124.2005

22/06/1967
22/27/1990
12/124/2005
45-04-2003
02-08-1995
123-02-2000
13.05.2004
17.09.1068
12.02.2405
06.04.27

Soluo da validao 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


Soluo:
Expresso 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


Diverso 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
006528
006528
006528

SL757317280BR
SL757317259BR
SL757317245BR
SL757317188BR

12/09/2005
12/09/2005
12/09/2005
12/09/2005

13/01/2005
13/01/2005
13/01/2005
13/01/2005

000002011347
000002011347
000002011347
000002011347

02240593000000602005011304
02240593000000612005011304
02240593000000622005011304
02240593000000632005011304

Incrementando o Shell com ERs

FIM

Você também pode gostar