sed, parte VIII: Back Reference

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ó



'&' só não é mais útil porque é só um.

No exemplo anterior, fizemos duas alterações no número.
Imagine porém, se ao invés de duas, tivéssemos que fazer várias edições numa linha.
Faríamos -e 's///' várias vezes? Não, daria muito trabalho. Vamos usar back reference!

Coloque cada coisa que você quer casar entre parênteses. Ou seja, faça sua regex normalmente, mas ponha trechos dela entre parẽnteses. A cada trecho entre parênteses, o sed guarda o que foi casado em '\1', '\2', ..., em quantos trechos você tenha criado, para que você possa trabalhar com várias coisas que casaram, no mesmo comando.
Lembrando que para usar parênteses no sed você tem que escapá-lo : \(\)

Vamos pegar o arquivo gerado no exemplo passado, o tels2.txt e explicitar mais cada trecho do telefone.

1. Código de área
O código de área é tudo que está do início até ')'. Como o analisador de linha do sed inicia no começo da linha, não é necessário explicitar isso, o ^ . Veja:
.*)

Colocando esse trecho entre parênteses(escapados) para depois referencia-lo :
\(.*)\)


Pronto. Se o sed achar um trecho do tipo: (nn), ele armazenará o que achar em '\1', onde 'n' é um caractere qualquer.

2. Primeira parte do número
São os quatro primeiros números do telefone, antes do hífen e depois dos parêntese.
Eles podem ser achados entre ')' e '-' . Porém, aqui tem um detalhe.
Como anterior mente já casamos o trecho inicial (nn), a análise de linha do sed está localizada após o ')', pois vamos colocar tudo num comando só, como você verá mais a frente. Portanto, não escrevemos:
).*-

E sim
.*-

Ou seja, catamos tudo, desde o ')', até o hífen.
Colocando entre parênteses, escapando :
\(.*\)

Agora, os 4 primeiros números, fora o DDD, está em '\2'.

3. Agora o analisador de linha do sed está localizado após o hífen e queremos pegar tudo do hífen até o final:
.*$

Colocando entre parênteses e escapando :
\(.*$\)

Esse trecho ficará em '\3'.

4. Agora vamos formatar a saída de modo a exibir uma mensagem bem mais detalhada sobre o telefone.
Pra isso, colocamos tudo isso junto num 's///':

cat tels2.txt | sed 's/\(.*)\)\(.*-\)\(.*$\)/DDD: \1  Primeira parte: \2   Segunda parte: \3/g'


Note que pegamos tudo em sequência, de uma vez: primeiro o DDD, depois os 4 seguintes números e depois os 4 finais.
É como se nós tivéssemos usado o sed para dizer como é o formato do telefone: (nn)NUMERO-NUMERO
Como todos são nesse formato, foi possível dividir em trechos: \1, \2 e \3

Isso só aconteceu graças a padronização dos dados.

E o resultado é:
DDD: (21)  Primeira parte: 3456-   Segunda parte: 7890
DDD: (85)  Primeira parte: 8888-   Segunda parte: 7766
DDD: (85)  Primeira parte: 9900-   Segunda parte: 1122

Nenhum comentário:

Veja também: