Incrementando o Shell com Expressões Regulares · O que são Expressões Regulares (ERs ou...
Transcript of Incrementando o Shell com Expressões Regulares · O que são Expressões Regulares (ERs ou...
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”.
Atualmente ERs são empregadas em vários comandos, linguagens e editores: ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find...
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.
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 sedsed - 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 trtr - 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 '[0123456789][0123456789][0123456789]' /etc/group- filtra todas as linhas que possuam três números em seqüência
$ grep '^[bcdfghjklmnpqrstvxywz]' /etc/passwd- filtra todas os usuários cujo o nome inicia por uma consoante
$ 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:
$ egrep '^.+$' /etc/profile- filtra as linhas com 1 ou mais caracteres, ou seja, linhas não vazias
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
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)$/CAMPOCAMPO - 1 - nome, 2 - versão e 3 para extensão
s/(.*)-(.*).(.* . .*)/... => escapar () e . (ponto mesmo)
sed 's/\(.*\)-\(.*\)\.\(.*\..*\)/\1 2 ou 3/' oused -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/' #nomelame
$ echo $SOURCE | sed -r 's/(.*)-(.*)\.(.*\..*)/\2/' # versão2.93
$ echo $SOURCE | sed -r 's/(.*)-(.*)\.(.*\..*)/\3/' # extensãotar.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
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
Metacaracter de negação de lista [^]
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 grupoawk ? + - - | ()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çõesa{2} casa com a letra “a” duas vezes
a{2,5} casa com a letra “a” duas a cinco vezesa{2,} casa com a letra “a” duas vezes ou mais
a? casa com “a” letra a zero vezes ou umaa* casa com a letra “a” zeros vezes ou maisa+ 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/196702/08/1995 17/09/1068 22/27/199012/02/2405 123/02/2000 12/124/200506/04/27 13-05-2004 45-04-200322-06-1967 17-09-1068 02-08-199522-27-1990 12-02-2405 123-02-200012-124-2005 06-04-27 13.05.200445.04.2003 22.06.1967 17.09.106822.27.1990 02.08.1995 12.02.240505..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
zeze@[email protected]@[email protected]@[email protected]@mane.com.comze@[email protected]@[email protected][email protected]
Desafio 3: Validar emails da lista emails.txt
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}$' [email protected]@[email protected]@[email protected][email protected]@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.txt006528SL757317280BR12/09/200513/01/200500000201134702240593000000602005011304006528SL757317259BR12/09/200513/01/200500000201134702240593000000612005011304006528SL757317245BR12/09/200513/01/200500000201134702240593000000622005011304006528SL757317188BR12/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
\1\t\2\t\3\t\4\t\5\t\6/' a.txtsed -r 's/^(.{6})(.{13})(.{10})(.{10})(.{12})(.*)$/
006528 SL757317280BR 12/09/2005 13/01/2005 000002011347 02240593000000602005011304006528 SL757317259BR 12/09/2005 13/01/2005 000002011347 02240593000000612005011304006528 SL757317245BR 12/09/2005 13/01/2005 000002011347 02240593000000622005011304006528 SL757317188BR 12/09/2005 13/01/2005 000002011347 02240593000000632005011304