O sed (Stream Editor) é uma ferramenta poderosa para manipulação de texto em fluxo (stream) no ambiente Unix/Linux. Ele permite realizar transformações em arquivos ou na saída de comandos de forma não interativa, sendo amplamente utilizado em scripts para automação de edições. Diferente de editores interativos como o vim ou nano, o sed opera linha a linha, aplicando comandos especificados e exibindo o resultado na saída padrão (ou alterando o arquivo in-place com a opção -i).

Nesta aula, exploraremos o comando de substituição s///, as flags que modificam seu comportamento, como endereçar linhas específicas e exemplos reais de uso. Ao final, você será capaz de usar sed para tarefas comuns de processamento de texto de forma eficiente.

Substituição (s///)

O comando s/// (substitute) é o mais utilizado do sed. Sua sintaxe básica é: sed 's/padrão/substituição/' arquivo. Ele substitui a primeira ocorrência do padrão (expressão regular) em cada linha pela substituição. O separador tradicional é a barra /, mas pode ser qualquer caractere (ex.: s|padrão|substituição|) para evitar escapes.

Exemplo: substituir a primeira ocorrência de "mundo" por "Bash" em cada linha do arquivo saudacao.txt.

$ cat saudacao.txt
Olá mundo!
Bom dia mundo!

$ sed 's/mundo/Bash/' saudacao.txt
Olá Bash!
Bom dia Bash!

O sed não altera o arquivo original a menos que a opção -i seja usada. Para salvar a saída em um novo arquivo, redirecione com >.

Flags (g, i)

As flags modificam o comportamento do comando s///. A flag g (global) faz com que todas as ocorrências do padrão na linha sejam substituídas, não apenas a primeira. A flag i (case-insensitive) ignora diferenças entre maiúsculas e minúsculas.

Exemplo com g:

$ echo "a a a" | sed 's/a/b/g'
b b b

Exemplo com i:

$ echo "Olá MUNDO" | sed 's/mundo/Bash/i'
Olá Bash

Flags podem ser combinadas: s/mundo/Bash/gi substitui todas as ocorrências de "mundo" independente de caixa.

Endereçamento de linhas

O sed permite aplicar comandos a linhas específicas usando endereços. A sintaxe é: sed 'endereço comando'. O endereço pode ser um número de linha, um intervalo (início,fim), ou uma expressão regular entre barras (/padrão/).

Exemplos:

  • sed '3s/foo/bar/' — substitui na linha 3.
  • sed '2,4s/foo/bar/' — substitui nas linhas 2 a 4.
  • sed '/erro/s/foo/bar/' — substitui apenas em linhas que contêm "erro".
  • sed '/^#/d' — exclui linhas que começam com # (comando d).

O endereçamento é essencial para edições seletivas, como alterar apenas um bloco de configuração.

Casos de uso

O sed é usado em scripts para tarefas repetitivas de edição. Exemplos comuns:

  • Substituir palavras em arquivos de configuração: sed -i 's/antigo/novo/g' config.txt
  • Remover linhas em branco: sed '/^$/d' arquivo
  • Extrair campos específicos: sed 's/.*: //' (remove tudo antes de ": ")
  • Inserir texto antes de uma linha: sed '/padrão/i\texto'
  • Combinar com pipe: comando | sed 's/erro/ERRO/g'

Dominar o sed aumenta significativamente a produtividade no terminal.

Boas práticas

  • Sempre teste o comando sem -i primeiro para verificar o resultado.
  • Use aspas simples para evitar expansão de variáveis no shell.
  • Escolha um separador que não apareça no padrão ou substituição (ex.: s|...|...|).
  • Para expressões regulares complexas, use a opção -E (extended regex).

Referências

Exercícios

  1. Usando sed, substitua a primeira ocorrência de "azul" por "vermelho" em cada linha do arquivo cores.txt. Mostre o comando.

    ✓ Resposta: sed 's/azul/vermelho/' cores.txt
  2. Como substituir todas as ocorrências de "foo" por "bar" em todo o arquivo, ignorando maiúsculas/minúsculas?

    ✓ Resposta: sed 's/foo/bar/gi' arquivo
  3. Escreva um comando sed que exiba apenas as linhas 3 a 6 de um arquivo (dica: use o comando p com a opção -n).

    ✓ Resposta: sed -n '3,6p' arquivo
  4. Usando endereçamento, substitua "erro" por "ERRO" apenas nas linhas que contêm a palavra "log".

    ✓ Resposta: sed '/log/s/erro/ERRO/g' arquivo
  5. Crie um comando sed que remova todas as linhas em branco de um arquivo (dica: linhas vazias contêm apenas o caractere de nova linha).

    ✓ Resposta: sed '/^$/d' arquivo