Este é o histórico da linha de comando de uma palestra que fiz para funcionários da Conectiva, sobre Expressões Regulares. O objetivo era apresentar todos os metacaracteres básicos e sua utilidade.
- Data: 17-Dez-2003
- Local: Auditório da Conectiva, Curitiba
- Duração: 2 horas
- Requisitos: Nenhum
Os Metacaracteres
$ # ^ $ + * {} () | ? [] .
O arquivo de exemplo
$ cd /etc $ cat passwd
Âncoras para início de fim de linha
$ grep root passwd $ grep ^root passwd $ grep bash$ passwd $ grep sh$ passwd $ grep 'sh$' passwd # proteger com aspas
Aspas duplas caso use variáveis
$ zzz=ro $ grep "$zzzot" passwd $ grep "${zzz}ot" passwd # proteger com {}
Use os colchetes para listar possibilidades para uma posição
$ echo Carlos | grep 'Carlos' $ echo Carlos | grep '[Cc]arlos' $ echo carlos | grep '[Cc]arlos' $ echo harlos | grep '[Cchfg]arlos'
Misture os metacaracteres a gosto
$ echo Carlos | grep '^[Cc]arlos$'
A lista serve para lidar com acentuação também
$ vi /tmp/acao.txt # acao, ACAO, Açao, aÇãO, AÇao, etc... $ cat /tmp/acao.txt | grep 'acao' $ cat /tmp/acao.txt | grep 'a[cç]ao' $ cat /tmp/acao.txt | grep 'a[cç][aã]o' $ cat /tmp/acao.txt | grep -i 'a[cç][aã]o' $ cat /tmp/acao.txt | grep '[Aa][CÇcç][AÃaã][Oo]' # todas possibilidades
Como casar linhas em branco
$ grep '^$' passwd
Listas negadas e intervalos
$ grep '^[aeiou]' passwd $ grep '^[bcdfghjklmnpqrstvwxyz]' passwd $ grep '^[^aeiou]' passwd $ grep '[^^]' passwd # negando o chapéuzinho $ grep '^[a-z]' passwd # o hífen indica intervalo $ grep '^[a-]' passwd # sem letras ao redor, hífen normal $ grep '^[-z]' passwd $ grep '^[az-]' passwd $ grep '^[0-9]' passwd # linhas iniciadas por números $ grep '[0-9]' passwd $ grep '[0-90-9]' passwd # errado $ grep '[0-9][0-9]' passwd # certo $ grep '[0-9][0-9][0-9]' passwd
Intervalos respeitam a tabela ASCII
$ man ascii
Classes POSIX respeitam o LOCALE
$ echo ááá | grep '[a-z]' $ echo $LANG $ echo ááá | grep '[[:lower:]]' $ echo ááá | grep '[0-9[:lower:]ABC ]'
O curinga: o ponto
$ grep '^[aeiou]' passwd # começa com vogal $ grep '^.[aeiou]' passwd # segunda letra vogal $ grep '^..[aeiou]' passwd # terceira letra vogal
Egrep e chaves para repetições
$ grep '^.......................[aeiou]' passwd $ grep '^.{25}[aeiou]' passwd # errado $ grep '^.{5}[aeiou]' passwd # errado $ grep '^.\{5\}[aeiou]' passwd # deve escapar! $ egrep '^.{5}[aeiou]' passwd # ou usar o egrep $ egrep 'f{995}' passwd # 995 efes $ egrep 'f{1,995}' passwd # de 1 a 995 efes
Mais sobre chaves
$ egrep '^.{5}[aeiou]' passwd # sexta letra vogal $ egrep '^.{4,5}[aeiou]' passwd # quinta ou sexta letra vogal $ egrep '^.{1,5}[aeiou]' passwd # de segunda a sexta letra vogal $ egrep '^.{5,}[aeiou]' passwd # sexta (ou mais) vogal
Linhas de tamanho fixo
$ echo aaaaaaaaaaaaaaaa | egrep 'a{6}' $ echo aaaaaaaaaaaaaaaa | egrep '^a{6}$' $ echo aaaaaaaaaaaaaaaa | egrep '^a{6,}$' $ echo aaaaaaaaaaaaaaaa | egrep 'a{6,}' $ echo aaaaaaaaaaaaaaaa | egrep 'a{2,6}'
Repetição de listas
$ egrep '[aeiou]{2}' passwd # duas vogais seguidas $ egrep '^.[aeiou]{2}' passwd # segunda e terceira vogais
? * e + são atalhos para as chaves {}
$ # ? {0,1} * {0,} + {1,}
O opcional ?
$ echo mala | egrep mala $ echo malas | egrep malas? $ echo mala | egrep malas? $ echo mala | egrep mal(as)? # erro! $ echo mala | egrep 'mal(as)?' # deve proteger com 'aspas' $ echo mal | egrep 'mal(as)?'
Não há como negar strings no meio da linha
$ echo mala | egrep '[^l][^a]' $ echo mala | egrep '(^la)' $ echo mala | egrep '(^ma)'
Grupos são legais!
$ echo mala | egrep '(((((((((a)))))))))' $ echo mala | egrep '((((((((((a))))))))))' $ echo mala | egrep '((((((((((a)))))))))' $ echo mala | grep '\(\(\(\(\(\(\(\(\(\(a\)\)\)\)\)\)\)\)\)\)'
Os retrovisores (máximo de nove, marca o texto e não a ER)
$ echo mala | egrep '(a)l\1' $ echo aja | egrep '(a).\1' $ echo a.a | egrep '(a).\1' $ echo a.a | egrep '([0-9]).\1' $ echo 7a7 | egrep '([0-9]).\1' $ echo 788 | egrep '([0-9])\1\1' # não casa $ echo 888 | egrep '([0-9])\1\1' # casa $ echo 888 | egrep '([0-9])\1{2}' # casa
Como procurar palavras repetidas
$ echo "por que que eu sou" | egrep '([a-z]{2,8}) \1' $ echo "por que qu eu sou" | egrep '([a-z]{2,8}) \1' $ echo "quero-quero" | egrep '([a-z]{2,8})-\1'
Usando ? * e +
$ echo b | egrep 'a*' $ echo b | egrep 'a+' $ echo b | egrep 'a?' $ echo ab | egrep 'a+' $ echo aaaaaa | egrep 'a+' $ echo aaaaaa | egrep '^a+$' $ echo aaaaaa | egrep '^a*$'
O tudo e o nada: ponto-asterisco .*
$ echo aaaaaa | egrep '.*' $ echo | egrep '.*' $ echo dayukafukdfkidrifhiioyohgoyiejeoueou | egrep '.*'
? * e + são gulosos!
$ echo "antes <b>bold<i>ital</i></b> texto" | sed 's/<.*>//g' $ echo "antes <b>bold<i>ital</i></b> texto" | sed 's/<.\{0,\}>//g' $ echo "antes <b>bold<i>ital</i></b> texto" | sed 's/<.\{1,\}>//g' $ echo "antes <b>bold<i>ital</i></b> texto" | sed 's/<.\{2,\}>//g' $ echo "antes <b>bold<i>ital</i></b> texto" | sed 's/<.\{2\}>//g' $ echo "antes <b>bold<i>ital</i></b> texto" | sed 's/<.\{1,2\}>//g' $ echo "antes <b>bold<i>ital</i></b> texto" | sed 's/<[^>]*>//g'
Ou isso ou aquilo
$ egrep 'root|ftp' passwd $ egrep '^root|FTP' passwd $ egrep '^(root|FTP)' passwd $ egrep '^(root|ftp)' passwd $ egrep '^(root|ftp).*\1' passwd
Procurar por palavras repetidas na mesma linha
$ cat passwd | egrep '(mail).*\1.*\1' $ cat passwd | egrep '([a-z]{3,}).*\1.*\1' $ cat passwd | egrep '^([a-z]{3,}).*\1.*\1' $ cat passwd | egrep '^([a-z]{3,}).*/home/\1' $ cat passwd | egrep '^([a-z]{3,}).*/var/spool/\1'
Usuários com shell e que o $HOME é diferente do login
$ cat passwd | egrep 'bash$' | egrep -v '^([a-z]{3,}).*/var/spool/\1' $ cat passwd | egrep 'bash$' | egrep -v '^([a-z]{3,}).*/home/\1'
Ou isso ou aquilo também se aplica a ERs complicadas!
$ cat passwd | egrep '^[aeiou]{2}|bash$' $ cat passwd | egrep '(^[aeiou]{2})|(bash$)' $ cat passwd | sed -nr 's/((^[aeiou]{2})|(bash$))/XXXX/gp'
Uma ER bem simples para casar um email
$ # [A-Za-z0-9._]+@([A-Za-z0-9-]+\.)+[A-Za-z]{2,6}
Trocando a ordem de campos
$ grep root passwd | cut -d: -f1,6 $ grep root passwd | cut -d: -f1,6 | sed -r 's/(.*):(.*)/\2:\1/'