Fundamentos do sed: Substituicao de Texto com o Editor de Fluxo

Fundamentos do sed: Substituicao de Texto com o Editor de Fluxo

O Que Voce Vai Aprender

  • Os cinco padroes essenciais do sed (substituir / deletar / imprimir / endereco / multi-expressao) no caminho mais curto para fluencia
  • O padrao seguro para edicoes -i (in-place) para parar de destruir arquivos
  • A diferenca entre BRE e ERE (-E) para que seu regex fique consistente com grep -E e awk

O padrao pratico

  • Sempre visualize na saida padrao primeiro, depois confirme com -i.bak
  • O delimitador nao precisa ser / -- use | ou # ao reescrever caminhos
  • Esquecer a flag g no final significa que apenas a primeira correspondencia por linha sera substituida

Premissas

  • SO: Ubuntu / Debian / familia RHEL Linux
  • Versao do sed: GNU sed (BSD sed no macOS usa sintaxe diferente para -i -- consulte a documentacao do fornecedor)

O Que e o sed?

sed (editor de fluxo) le a entrada linha por linha, aplica um script de edicao e escreve na saida padrao. Diferente de editores interativos como o Vim, o sed foi feito para uso nao interativo dentro de pipelines do shell -- normalizacao de logs, reescrita de configuracoes, preprocessamento de texto.

$ echo "hello world" | sed 's/world/Linux/'
hello Linux

O comando s/old/new/ (substituicao) representa aproximadamente 80% do uso real do sed.

Por Que Visualizar na Saida Padrao Primeiro?

sed -i sobrescreve o arquivo diretamente. Se voce perceber depois que o padrao estava errado ou esqueceu de escapar uma /, a recuperacao e dificil. Sempre visualize na saida padrao, depois confirme com -i.bak -- este e o unico habito confiavel.

# 1. Visualizar na saida padrao
$ sed 's/foo/bar/g' config.txt

# 2. Confirmar com backup
$ sed -i.bak 's/foo/bar/g' config.txt

# 3. config.txt.bak e gerado automaticamente
$ ls config.txt*
config.txt  config.txt.bak

Usar -i sem sufixo de backup e arriscado para trabalho em producao. Torne -i.bak um habito -- reverter e apenas mv config.txt.bak config.txt.

1. Substituicao: s/old/new/

1-1. Primeira correspondencia em cada linha (padrao)

$ echo "apple apple apple" | sed 's/apple/orange/'
orange apple apple

1-2. Todas as correspondencias na linha (flag g)

$ echo "apple apple apple" | sed 's/apple/orange/g'
orange orange orange

Esquecer o g e o erro #1 do sed. Se "apenas algumas correspondencias mudaram," verifique primeiro se falta o g.

1-3. Sem diferenciar maiusculas/minusculas (flag I)

$ echo "Apple APPLE apple" | sed 's/apple/orange/gI'
orange orange orange

A flag I e uma extensao do GNU sed. Evite-a em scripts portaveis (o sed POSIX nao a suporta).

2. Mudando o Delimitador de /

Quando o padrao contem caminhos como /usr/local, escapar cada / rapidamente se torna ilegivel. O caractere logo apos s e o delimitador -- escolha |, # ou , para manter a legibilidade.

# Ruim: inferno de barras invertidas
$ sed 's/\/usr\/local\/bin/\/opt\/bin/' file

# Bom: pipe como delimitador
$ sed 's|/usr/local/bin|/opt/bin|' file

# Tambem bom: hash como delimitador
$ sed 's#/usr/local/bin#/opt/bin#' file

Mudar o delimitador elimina 80% dos bugs de substituicao. Para reescrita de caminhos, | ou # e o padrao de fato.

3. Enderecos: Direcionando Linhas Especificas

Todo comando de edicao do sed pode receber um prefixo de endereco que restringe em quais linhas ele e aplicado.

3-1. Por numero de linha

$ sed '3s/foo/bar/' file       # Apenas linha 3
$ sed '1,5s/foo/bar/g' file    # Linhas 1-5
$ sed '10,$s/foo/bar/g' file   # Linha 10 ate o final ($ = ultima linha)

3-2. Por padrao

# Apenas em linhas contendo "ERROR"
$ sed '/ERROR/s/foo/bar/g' file

# Entre /START/ e /END/
$ sed '/START/,/END/s/foo/bar/g' file

3-3. Negacao (!)

# Todas as linhas exceto a linha 1
$ sed '1!s/foo/bar/g' file

# Tudo exceto linhas de comentario (comecando com #)
$ sed '/^#/!s/foo/bar/g' file

4. Deletar (d) e Imprimir (p)

4-1. Deletar linhas

$ sed '/^$/d' file              # Deletar linhas vazias
$ sed '/^#/d' file              # Deletar linhas de comentario
$ sed '1,5d' file               # Deletar linhas 1-5
$ sed '$d' file                 # Deletar a ultima linha

4-2. Imprimir apenas linhas especificas (-n + p)

Por padrao, o sed imprime todas as linhas. A flag -n suprime a saida padrao, entao voce so ve as linhas que explicitamente imprimir com p.

# Imprimir linhas contendo "ERROR" (como grep "ERROR")
$ sed -n '/ERROR/p' file

# Imprimir linhas 10-20
$ sed -n '10,20p' file

sed -n 'Np' e mais rapido e claro que head -n N | tail -1 para extrair uma unica linha.

5. Multiplas Edicoes em Uma Passagem

5-1. Multiplas expressoes -e

$ sed -e 's/foo/bar/g' -e 's/hoge/fuga/g' file

5-2. Separadas por ponto e virgula (GNU sed)

$ sed 's/foo/bar/g; s/hoge/fuga/g' file

5-3. Arquivo de script com -f

Salve conjuntos de transformacoes reutilizaveis em um arquivo.

$ cat replace.sed
s/foo/bar/g
s/hoge/fuga/g
/^#/d

$ sed -f replace.sed file

6. BRE vs ERE: Devo Sempre Usar -E?

O sed usa por padrao BRE (Expressoes Regulares Basicas). Usar +, ?, | ou (...) requer escape com barra invertida, o que fica feio rapidamente. Adicionar -E muda para ERE (Expressoes Regulares Estendidas) -- a mesma variante que grep -E e awk usam.

6-1. BRE (padrao)

# Grupos e quantificadores requerem \( \) e \{ \}
$ echo "2026-05-20" | sed 's/\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\)/\3\/\2\/\1/'
20/05/2026

6-2. ERE (-E)

# Sem escape -- muito mais facil de ler
$ echo "2026-05-20" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/'
20/05/2026

Torne -E seu padrao. O escape do BRE coloca carga cognitiva nos revisores e leva a bugs passando despercebidos.

6-3. Retro-referencias (\1, \2, ...)

Grupos capturados sao referenciados como \1, \2, etc. na substituicao. Mesma sintaxe em BRE e ERE.

# "Sobrenome, Nome" -> "Nome Sobrenome"
$ echo "Doe, John" | sed -E 's/(.+), (.+)/\2 \1/'
John Doe

7. Armadilhas e Como Evita-las

Top 5 armadilhas do sed

  1. Executar -i sem visualizar -- irrecuperavel. Sempre visualize primeiro, depois use -i.bak
  2. Flag g ausente -- apenas uma correspondencia por linha e alterada
  3. Esquecer de mudar o delimitador -- escape de / torna padroes ilegveis
  4. Misturar BRE e ERE -- escolha um e mantenha (-E recomendado)
  5. Tratar * ou . como literais -- sao metacaracteres regex; escape-os

7-1. Escapando metacaracteres literais

# Ruim: . corresponde a qualquer caractere
$ echo "192x168x0x1" | sed 's/192.168.0.1/X/'
X

# Bom: escape o ponto
$ echo "192x168x0x1" | sed 's/192\.168\.0\.1/X/'
192x168x0x1

7-2. Incorporando variaveis do shell

Variaveis do shell nao expandem dentro de aspas simples. Mude para aspas duplas -- mas cuidado com $ e \ dentro delas.

NEW="bar"

# Ruim: $NEW e literal
$ sed 's/foo/$NEW/g' file

# Bom: aspas duplas para expansao
$ sed "s/foo/$NEW/g" file

Se $NEW contiver /, & ou \, a substituicao quebra. Mude o delimitador ou sanitize o valor antes de injeta-lo.

8. Receitas Praticas

Templates para copiar e colar

# Converter CRLF para LF
sed -i.bak 's/\r$//' file

# Remover linhas vazias e comentarios #
sed -e '/^$/d' -e '/^#/d' /etc/nginx/nginx.conf

# Mascarar enderecos IP
sed -E 's/\b([0-9]{1,3}\.){3}[0-9]{1,3}\b/x.x.x.x/g' access.log

# Remover espacos em branco no final
sed -i.bak 's/[[:space:]]*$//' file

# Inserir uma linha antes de linhas correspondentes a um padrao
sed -i.bak '/^pattern/i\
inserted line before' file

# Reescrever um valor YAML (apos chave:)
sed -i.bak -E 's/^(version:\s*).*/\1"1.2.3"/' config.yaml

sed vs awk vs grep: Quando Usar Qual

Tarefa Melhor ferramenta
Substituicao simples de strings sed
Filtrar linhas correspondentes (grep-like) grep / sed -n
Processamento por colunas (campos, soma) awk
Transformacoes multi-linha sed comando N ou awk
Dados estruturados (JSON / YAML) jq / yq

sed brilha em: edicoes de linha unica em fluxo, baixo consumo de memoria, disponivel em todo Unix sed tem dificuldade com: dados colunares, formatos estruturados, logica multi-linha -- mude para awk ou jq quando as coisas ficarem complexas

O Que Ler em Seguida