26
Incrementando o Shell com Expressões Regulares Rudson Ribeiro Alves - UVV [email protected]

Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

  • Upload
    lethuy

  • View
    229

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

Incrementando o Shell com Expressões Regulares

Rudson Ribeiro Alves - [email protected]

Page 2: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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.

Page 3: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · 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

Page 4: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 5: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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'

Page 6: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 7: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 8: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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)- ...

Page 9: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 10: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 11: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 12: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 13: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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!

Page 14: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 15: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 16: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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 ()

Page 17: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 18: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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 [^]

Page 19: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 20: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 21: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 22: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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]'

Page 23: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 24: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 25: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

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

Page 26: Incrementando o Shell com Expressões Regularesrra.etc.br/linux/apresentacoes/Incrementando_o_Shell_com_ER.pdf · ed, grep, sed, awk, vi, emacs, Perl, PHP, java, mysql, python, find

Incrementando o Shell com ERs

FIM