sed, parte VI: Expressões Regulares

parte I: O que é e para que serve
parte II: Enviando dados pro sed
parte III: Selecionando as linhas em que vamos trabalhar
parte IV: Substituindo
parte V: Scripts em sed
parte VI: Expressões Regulares
parte VII: Referenciando com &
parte VIII: Back Reference
parte IX: Hold Space ou Espaço Reserva
parte X: Por onde prosseguir e Considerações Finais
parte XI: Comandos de uma linha só



Este tópico tem assunto pra livros e livros, pois, sem dúvida, é a ferramenta mais útil e utilizada pra quem quer processar informações na forma de texto.

Há muita, mas muita coisa na internet, que podem facilitar muito a vida de quem precisa trabalhar com sed, awk, Perl e outras linguagens que façam uso de expressão regular, pois não existe uma regra geral de escrita, varia muito de acordo com a criatividade de quem escreve.

Existem até competições minimalistas, pra ver quem consegue fazer um mesmo trabalho utilizando de expressões regulares mínimas.

Se for pesquisar algo e em inglês, ela é muito conhecida por regex (regular expressions).

Expressões regulares são, basicamente, um conjunto de caracteres.
Mas esse conjunto pode representar muitas coisas, e de uma maneira bem simples (as vezes não).

Já conhecemos dois elementos, ^ e $.
Vamos usar o que sabemos pra fazer algo.
Como você faria, por exemplo pra eliminar os comentários de um script?
Lembrando que comentários sempre começam com '#' no início da linha.

A regex pra isso é : ^#
Vamos usar o arquivo syslog.conf(se nao tiver, tente o sysctl.conf) como exemplo:
cat /etc/syslog.conf | sed '/^#/d'

Você poderia ter usado s/^#// , mas aí teria digitado 's' e '/' à toa. Mas, mais importante do que fazer da maneira mais simples, é conseguir fazer. Com o tempo, e preguiça, você vai digitando cada vez menos.

Suponha agora que você quer transformar uma linha em branco de seu editor em texto em '<p>', que é o parágrafo em HTML. Uma linha em branco nada mais é que: ^$
Ou seja, nada entre o começo e o fim. Faz todo o sentido, né?

cat txt2html | sed 's/^$/<p>/g'

Pronto. Com isso e com o comando 'i' e 'a', já pode iniciar um soft que converte seu arquivo de texto em código HTML ;)

Falei sério.

Com o uso da flag 'd' de delete, vemos somente o que restou.
Sempre que quisermos ver o que o casou("matched"), use as flags '-n' e 'p':
cat /etc/syslog.conf | sed -n '/^#/p'

Outros caracteres usados em regex:
.    Pode substituir qualquer caractere: p.p casa tanto com 'psp', um playstation portável ou um palavrão abreviado.

*    Casa com qualquer quantidade do caractere anterior. No caso de 'p.p', só casa com 3 caracteres. Se fosse 'p.*p', casa qualquer coisa que comece com p e termine com p, inclusive 'pp' ou o palavrão na forma formal.

[]    Casa com qualquer caractere dentro desses colchetes.
Por exemplo, quer testar se alguma linha do arquivo começa com as letras 'a', 'b' ou 'c': ^[abc]
Se usar '-', você define uma faixa :
[a-z], de 'a' até 'z'
[0-9]: de 0 até 9


- Classe de caracteres

Em vez de escrevermos [a-z], [A-Z], [0-9]...esses conjuntos já vem em forma de classes pré-definidas, pois são de uso corriqueiro por quem usa regex.

Por exemplo, quer saber que linhas de um arquivo começam por um caractere alfabético?
cat /etc/sysctl.conf | sed -n '/^[:alpha:]/p'

E o que fica se você apagar tudo que não começa por um caractere alfabético? Veja:
cat /etc/sysctl.conf | sed '/^[:alpha:]/d'

A seguir, a lista completa das classes de caracteres do GNU sed:

[[:alnum:]]    Alfabéticos e númericos [a-z A-Z 0-9]
[[:alpha:]]     Alfabéticos [a-z A-Z]
[[:blank:]]     Caractere em branco, espaço ou tab [ \t]
[[:cntrl:]]      Caracteres de controle [\x00-\x1F\x7F]
[[:digit:]]      Números [0-9]
[[:graph:]]    Qualquer caractere visível(ou seja, exceto em branco) [\x20-\x7E]
[[:lower:]]     Letras minúsculas [a-z]
[[:upper:]]    Letras maiúsculas [A-Z]
[[:print:]]      Caracteres visíveis (ou seja, exceto os de controle) [\x20-\x7E]
[[:punct:]]     Pontuação [-!"#$%&'()*+,./:;<=>?@[\\\]_`{|}~].
[[:space:]]     Espaço em branco [ \t\r\n\v\f]
[[:xdigit:]]     Número hexadecimais [0-9 a-f A-F]


- Expressões regulares em intervalos de endereços

Vimos um exemplo de endereços usando a numeração das linhas.
Mas raramente sabemos disso. Na real, o texto terá dezenas, centenas ou milhares de linhas e você não faz a mínima ideia qual o número da linha de determinada informação.

Reescreva a frase.txt como:
O vento do duende
vem de roxo
quando pisca
na inconsciência
do javali.

Em vez de usar números para definir linhas, podemos tentar casar uma parte do texto.
Por exemplo, vamos exibir da segunda até a quarta linha.
cat frase.txt | sed -n '/vem de roxo/,/na inconsciência/p'

Note que:
/vem de roxo/ = linha 2
/na inconsciência/ = linha 4

Assim, não precisamos nos importar com a numeração, e sim com um texto que podemos casar.
Então, o sed acha as linhas e procede automaticamente.

Pro sed, '2' e '/vem de roxo/' são a mesma coisa. Então, podemos fazer:
cat frase.txt | sed -n '2,/na inconsciência/p'

Substituições com expressões regulares, são, sem dúvida, a combinação mais poderosa do sed.

Nenhum comentário:

Veja também: