SED - substituir apenas a ocorrência N de uma string

Publicado por Fábio Berbert de Paula em 08/06/2020

[ Hits: 3.867 ]

Blog: https://fabio.automatizando.dev

 


SED - substituir apenas a ocorrência N de uma string



Suponha que você precisa fazer uma dieta e possui o seguinte cardápio semanal:

echo churrasco churrasco churrasco churrasco churrasco churrasco churrasco

O objetivo é substituir os pratos do final de semana, que no caso seriam as ocorrências 6 e 7, por salada. Antes:

churrasco churrasco churrasco churrasco churrasco churrasco churrasco

Depois:

churrasco churrasco churrasco churrasco churrasco salada salada

Com o sed podemos fazer assim:

echo churrasco churrasco churrasco churrasco churrasco churrasco churrasco| sed 's/churrasco/salada/6; s/churrasco/salada/6'

Repare que usei o padrão 's/antes/depois/N', onde N é o número da ocorrência. Porém repeti a ocorrência 6 duas vezes. O motivo é que na segunda passada, o churrasco de domingo é a ocorrência 6, visto que sábado não é mais churrasco.

Também posso usar a seguinte sintaxe:

echo churrasco churrasco churrasco churrasco churrasco churrasco churrasco| sed 's/churrasco/salada/6g'

que significa alterar todas as ocorrências a partir da N=6.

Usando o sed via arquivo

O grande problema na sintaxe anterior é que ela não funciona exatamente assim para arquivos, visto que o sed trata uma linha por vez. Então podemos contornar o problema usando uma sintaxe um pouco mais avançada...

Dado um arquivo "cardapio.txt" com o seguinte conteúdo:

churrasco
churrasco
churrasco
churrasco
churrasco
churrasco
churrasco

Se executarmos o comando abaixo não acontecerá nada, pois só há uma ocorrência de churrasco por linha ao invés de sete:

sed 's/churrasco/salada/6' cardapio.txt
churrasco
churrasco
churrasco
churrasco
churrasco
churrasco
churrasco


A solução é a sintaxe abaixo, cuja explicação vem a seguir:

sed ':a ; N; $! ba ; s/churrasco/salada/6g' cardapio.txt
churrasco
churrasco
churrasco
churrasco
churrasco
salada
salada


Explicando:
  • :a - crie uma "label" chamada "a" no buffer de memória;
  • N - leia a próxima linha e a armazene;
  • $! - enquanto não for fim de arquivo;
  • ba - retorne (back) para a label "a".

Com esse truque o sed armazenou todo o conteúdo do arquivo em memória e irá processá-lo com um conteúdo só ao invés de ler linha por linha. Na verdade ele leu linha por linha ( :a; N; $! ba ), mas só depois de ler todas elas que ele processou a expressão regular.

Espero ter explicado com clareza o suficiente.

Até a próxima!

Outras dicas deste autor

Habilitando conversão de PDF em Imagem usando o ImageMagick

Lista de discussão sobre a certificação LPI (Linux Professional Institute)

Resolvendo flash sem som no Firefox

Primeira Conferencia Hacker no Brasil

Flashback: Como o Google via a internet em 2001

Leitura recomendada

Informações completas sobre os arquivos numa pasta

Eliminando linhas de comentário ou linhas em branco no Linux

Múltiplas expressões no SED

Listar comandos mais utilizados (via histórico de shell)

Leitor de arquivos ePub

  

Comentários
[1] Comentário enviado por maurixnovatrento em 08/06/2020 - 11:53h


Muito bom.

___________________________________
Conhecimento não se Leva para o Túmulo.



Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts