sed, parte VII: Referenciando com &

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ó



Sempre que o sed casa(match) algo, ele armazena esse algo em &.
Por exemplo: s/javali/porco/

Nesse caso, &=javali
Então, fazendo:
s/javali/& e do porco/


A frase se torna: O vento do duente vem de roxo quando pisca na inconsciência do javali e do porco.


Vamos usar o & para repetir cada número do teste.txt:
cat teste.txt | sed 's/./&&/g'

. representa um único caractere. Como, no teste.txt, cada linha possui somente um caractere, que é um número, o & armazenarar o valor desse número, em cada linha.
Estamos substituindo um número(.), por ele duas vezes(&&).

Vamos para um exemplo prático.
Vamos supor que você tem um site que pede o telefone do cliente, com DDD+número, sem parênteses ou hífens.

Crie tels.txt
2134567890
8588887766
8599001122

Porém, exibir um número assim é confuso. Pra armazenar no seu banco de dados, ok.
Mas pra exibir isso pro cliente, não é interessante.
Então vamos fazer um script em sed que pegue um txt contendo telefones e transforme no padrão:
(DDD)NUMEROS-NUMEROS

1. Vamos pegar os dois primeiros números e transformar neles envoltos de parênteses.
Para pegar os 2 primeiros números do início de cada linha:
's/^[[:digit:]][[:digit:]]/(&)/g'

Ou seja, o que vai casar, dois dígitos seguidos, a partir do início da linha, fica armazenado na & e vamos colocar, no lugar desses dois números, isso (&).

Mas é muito chato escrever [[:digit:]] duas vezes, pois, e se fossem 10 números e não só 2?

Pra repetição, usamos o número de vezes que queremos repetir entre colchetes: {n}
No nosso caso, seria: [[:digit:]]{2}

Vamos colocar isso no script, lembrando que temos que 'escapar' o '{' e o '}':
's/^[[:digit:]]\{2\}/(&)/g'

2. Depois de colocar os parênteses, devemos colocar um hífen após 4 dígitos.
Como dizer isso pro sed? Simples. Seja 'abcd' os números, queremos substituir isso por 'abcd-'.
Mas não pode ser quatro números quaisquer, tem que ser os 4 dígitos após o parêntese ).
Então, fica:
's/)[[:digit:]]\{4\}/&-/g'

3. Lembrando que o comando 2 só funciona se a substituição referente ao item 1 já tiver ocorrido.
Ou seja, vamos colocar os comandos em sequência e usaremos a flag '-e' para edições múltiplas.
O resultado é:
cat tels.txt | sed -e 's/^[[:digit:]]\{2\}/(&)/' -e 's/)[[:digit:]]\{4\}/&-/' > tels2.txt

E obtemos:
(21)3456-7890
(85)8888-7766
(85)9900-1122

Nenhum comentário: