O sed (Stream Editor) é uma ferramenta poderosa para processamento de texto em scripts shell. Após dominar os comandos básicos de substituição, é hora de explorar funcionalidades avançadas que permitem manipular arquivos com precisão cirúrgica. Nesta aula, veremos como deletar e inserir linhas, utilizar grupos de captura e backreferences, editar arquivos diretamente com a opção -i, e aplicar esses conceitos em exemplos do dia a dia.

Com o sed avançado, você poderá automatizar tarefas repetitivas de edição de configurações, logs e dados estruturados, tornando seus scripts mais robustos e flexíveis.

Deleção e inserção

O sed permite deletar linhas com o comando d e inserir linhas com i (antes) e a (após). Diferente da substituição, esses comandos afetam linhas inteiras. É possível endereçar linhas por número, padrão ou intervalos.

Por exemplo, para deletar a terceira linha de um arquivo: sed '3d' arquivo. Para deletar linhas que contêm a palavra "erro": sed '/erro/d' arquivo. Para inserir uma linha antes da linha 5: sed '5i\nova linha' arquivo. Note a barra invertida dupla para escapar a nova linha.

# Deletar linhas 2 a 4
sed '2,4d' arquivo.txt

# Inserir linha antes de cada linha que contém "INÍCIO"
sed '/INÍCIO/i\--- MARCADOR ---' arquivo.txt

# Inserir linha após a última linha (usando $)
sed '$a\Fim do arquivo' arquivo.txt

Grupos e backreferences

Em expressões regulares, grupos são delimitados por parênteses \( e \) (escapados) e podem ser referenciados no lado direito da substituição com \1, \2, etc. Isso permite reordenar ou extrair partes do texto.

Por exemplo, para trocar "nome:valor" por "valor:nome": sed 's/\(.*\):\(.*\)/\2:\1/'. O primeiro grupo captura tudo antes de ':', o segundo depois. As backreferences \1 e \2 são usadas na substituição.

# Inverter ordem de campos separados por vírgula
echo "João,30,Engenheiro" | sed 's/\([^,]*\),\([^,]*\),\(.*\)/\3,\2,\1/'

# Extrair apenas o domínio de e-mails
echo "user@example.com" | sed 's/.*@\(.*\)/\1/'

Edição in-place (-i)

A opção -i (ou --in-place) faz com que o sed edite o arquivo diretamente, em vez de exibir o resultado na saída padrão. É possível fornecer uma extensão para backup, ex.: -i.bak cria um backup com extensão .bak.

Cuidado: a edição in-place é destrutiva; sempre teste o comando sem -i primeiro. Exemplo: substituir "foo" por "bar" no arquivo config.txt e salvar backup: sed -i.bak 's/foo/bar/g' config.txt.

# Substituir todas as ocorrências de "antigo" por "novo" no arquivo, sem backup
sed -i 's/antigo/novo/g' documento.txt

# Com backup: cria documento.txt.bak
sed -i.bak 's/antigo/novo/g' documento.txt

Exemplos

Vamos consolidar com exemplos práticos que combinam os conceitos:

1. Remover linhas em branco e comentários de um arquivo de configuração:

sed -i '/^#/d; /^$/d' config.ini

2. Adicionar uma linha de cabeçalho no início de um arquivo CSV:

sed -i '1i\nome,idade,profissao' dados.csv

3. Transformar logs no formato "data: mensagem" para "mensagem (data)":

sed -i 's/\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\): \(.*\)/\2 (\1)/' log.txt

4. Inserir uma linha após cada linha que contém "ERROR":

sed -i '/ERROR/a\Verificar urgente!' log.txt

Boas práticas e observações finais

Sempre teste comandos sed sem -i para verificar o resultado. Use expressões regulares com cuidado para evitar efeitos colaterais. Prefira sed para transformações simples e awk para processamento mais complexo. Lembre-se de que o sed opera linha a linha, então comandos que dependem de contexto multilinha requerem truques adicionais.

Referências

Exercícios

  1. Dado o arquivo 'numeros.txt' com linhas contendo números, use sed para deletar todas as linhas ímpares (1,3,5,...).
  2. ✓ Resposta:
    sed -i '1~2d' numeros.txt
  3. Em um arquivo 'pessoas.txt' com linhas no formato "nome:idade:altura", use sed para trocar a ordem para "altura:nome:idade".
  4. ✓ Resposta:
    sed -i 's/\([^:]*\):\([^:]*\):\(.*\)/\3:\1:\2/' pessoas.txt
  5. Use sed para inserir a linha "" antes da primeira linha que contém "" em um arquivo HTML.
  6. ✓ Resposta:
    sed -i '//i\' arquivo.html
  7. Crie um comando sed que substitua todas as ocorrências de "192.168.1." por "10.0.0." em um arquivo de configuração de rede, editando in-place com backup (.bak).
  8. ✓ Resposta:
    sed -i.bak 's/192\.168\.1\./10.0.0./g' rede.conf
  9. Dado o arquivo 'notas.txt' com linhas "aluno:nota", use sed para adicionar uma linha "---" após cada linha onde a nota é maior ou igual a 7.
  10. ✓ Resposta:
    sed -i '/:[7-9]$/a\---' notas.txt