domingo, 22 de julho de 2012

Expressões regulares com o grep

O grep é um utilitário de linha de comando para busca em arquivos. O comando grep realiza uma pesquisa nos arquivos de entrada, a procura de linhas que contenham a palavra-chave informada e no resultado exibe as linhas encontradas na saída padrão.

Este utilitário possui diversas opções na linha de comando e algumas são para invocar as variantes do grep. Por padrão, o grep interpreta a palavra-chave como uma expressão regular básica (BRE). A variante egrep, invocado pela opção -E ou executado diretamente pelo comando egrep, interpreta a palavra-chave como uma expressão regular extendida (ERE).

Uma expressão regular é um padrão que descreve um conjunto de strings. É uma especificação de um modelo padrão de texto. Diversos símbolos ou caracteres especiais são compostos em união com caracteres literais e formam uma sequência, similar a uma expressão aritmética, podendo ter pequenas expressões para compor o todo. Uma expressão regular cria uma regra para ser interpretada na busca, uma condição para ser cumprida.

As expressões regulares são úteis quando não se lembra exatamente dos caracteres que compõem o texto ou na procura por uma sequência de caracteres com uma característica comum, por exemplo um número de telefone, e assim temos a ideia das variações possíveis. Também é uma maneira de procurar caracteres em posições específicas como no começo ou no fim de uma linha, ou palavra.

Observação: Apesar de semelhantes, os curingas usados ao especificar nomes de arquivos, como *.txt, relatorio.{xls,doc} e SDC500??.JPG, não são expressões regulares, os significados dos símbolos são diferentes das expressões.

Como visto, uma expressão regular é formada por caracteres com funções especiais em conjunto com caracteres normais de texto, definindo assim um padrão para a pesquisa. Cada caractere especial realiza uma operação específica.

No GNU grep não há diferença de funcionalidade entre a sintaxe básica e extendida. As descrições dos caracteres especiais apresentados a seguir são para as expressões regulares extendidas. As expressões regulares básicas possui algumas particularidades que estão descritas ao final deste artigo:

^ (circunflexo) Simboliza o início de uma linha. Se usado assim, ^palavra , serão pesquisadas linhas que iniciem com a "palavra".

$ (cifrão) Simboliza o fim de uma linha. Se usado assim, palavra$ , serão pesquisadas linhas que terminem com a "palavra".

[ ] (lista) Compara qualquer caractere único fornecido na lista. Se usado assim, n[ãa]o , serão pesquisadas linhas que contenham "não" ou "nao".

[^] (lista negada) Nega qualquer caractere único fornecido na lista. Se usado assim, palavr[^iou] , serão pesquisadas linhas que contenham "palavr?" não terminada com i, o ou u.

[-] (intervalo em lista) Compara qualquer caractere dentro do intervalo. Se usado assim, sala-[a-d] , serão pesquisadas linhas que contenham "sala-" mais um caractere entre a e d. (a ordem seguida é a ordem dos caracteres na tabela ASCII)

| (ou) Indica uma coisa ou outra. Se usado assim, (pato|ganso) , serão pesquisadas linhas que contenham "pato" ou "ganso".

. (ponto) Simboliza qualquer caractere numa certa posição. Se usado assim, palavra. , serão pesquisadas linhas que contenham "palavra" mais um caractere, por exemplo palavra1,palavra2,palavraa etc.

* (tanto faz) Indica que tanto faz a quantidade do caractere anterior. Se usado assim, palavras* , serão pesquisadas linhas que contenham "palavra", "palavras", "palavrass", "palavrasss" etc.

.* (curinga) Simboliza qualquer caractere em qualquer quantidade. Se usado assim, ^nome.*sobrenome$ , serão pesquisadas linhas que iniciem com "nome" e terminem com "sobrenome", com qualquer coisa no meio.

+ (tem que ter) Indica que deverá ter o caractere anterior em qualquer quantidade. Se usado assim, palavras+ , serão pesquisadas linhas que contenham "palavras", "palavrass", "palavrasss" etc.

? (opcional) Indica que o caractere anterior é opcional. Se usado assim, palavras? , serão pesquisadas linhas que contenham "palavras" ou "palavra".

{ } (chaves) Indica o número de repetições do caractere anterior. Se usado assim, p.{5} , serão pesquisadas linhas que contenham palavras iniciadas com "p" e mais cinco caracteres quaisquer. Ou pode indicar um intervalo. Se usado assim, p.{5,7} , indica "p" mais cinco a sete caracteres. Se usado assim, p.{5,} , indica "p" mais cinco ou mais caracteres quaisquer.

\b (borda) Indica uma borda de palavra. Marca os limites de uma palavra, ou seja, onde ela começa e/ou termina. Se usado assim, \bpala , serão pesquisadas linhas que contenham palavras iniciadas com "pala". Se usado assim, vra\b , serão pesquisadas linhas que contenham palavras terminadas com "vra".

\B (fora da borda) Indica que a palavra-chave não está nas bordas de uma palavra. Se usado assim, \Bala , serão pesquisadas linhas que contenham palavras com o padrão "ala" em algum lugar fora do início ou fim, por exemplo "palavra".


Exemplos de uso de expressões regulares no grep:

grep ^usuario /etc/passwd

grep bash$ /etc/passwd

grep ^.*5[0-9][0-9] /etc/group

grep '\[' /etc/*
grep '[[]' /etc/*

egrep \(root\|ftp\) /etc/group
egrep '(root|ftp)' /etc/group
grep -E '(root|ftp)' /etc/group
grep '\(root\|ftp\)' /etc/group
grep \\\(root\\\|ftp\\\) /etc/group

grep -E '(((1[0-9]|[1-9]?)[0-9]|2([0-4][0-9]|5[0-5]))\.){3}((1[0-9]|[1-9]?)[0-9]|2([0-4][0-9]|5[0-5]))' /var/log/secure

grep -E '([0-9]{4}.?){3}[0-9]{4}' arquivo_com_número_de_cartão_de_crédito

grep -E '([0-9]{3}.?){3}[0-9]{2}' arquivo_com_número_de_CPF

grep -E '[0-9]{2}/[0-9]{2}/[0-9]{4}' arquivo_com_data


Considerações a respeito das expressões regulares:

Nas expressões regulares básicas os caracteres especiais ?, +, {, |, (, e ) perdem seus significados especiais, no lugar use as versões com barra invertida \?, \+, \{, \|, \(, e \). A opção -E do grep ou o uso do comando egrep não necessita disto.

Se precisar utilizar um caractere especial como um caractere literal, utilize \ (barra invertida) para anular (escape) o efeito do caractere especial ou proteja-o em uma lista [ ].

Alguns caracteres especiais usados nas expressões regulares precisam estar protegidos da interpretação do shell. Para protegê-los utiliza-se o caractere \ (barra invertida) ou proteja tudo com ' (apóstrofos).


A expressão regular é um recurso poderoso e é suportada por muitos comandos do Linux, incluindo find, sed e awk. Também é usada em editores de texto e em linguagens de programação para procura e substituição de texto.

Nenhum comentário:

Postar um comentário