sed avançado
Esta aula aprofunda o uso do sed, abordando técnicas avançadas como deleção e inserção de linhas, uso de grupos e backreferences, edição in-place com a flag -i, e exemplos práticos. O objetivo é capacitar o aluno a realizar transformações complexas em arquivos de texto de forma eficiente.
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.txtGrupos 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.txtExemplos
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.ini2. Adicionar uma linha de cabeçalho no início de um arquivo CSV:
sed -i '1i\nome,idade,profissao' dados.csv3. Transformar logs no formato "data: mensagem" para "mensagem (data)":
sed -i 's/\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\): \(.*\)/\2 (\1)/' log.txt4. Inserir uma linha após cada linha que contém "ERROR":
sed -i '/ERROR/a\Verificar urgente!' log.txtBoas 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
- GNU sed manual
- sed man page (die.net)
- Tutorialspoint - sed tutorial
- The Geek Stuff - Advanced sed substitution
- Stack Overflow - sed tag
Exercícios
- Dado o arquivo 'numeros.txt' com linhas contendo números, use sed para deletar todas as linhas ímpares (1,3,5,...).
- Em um arquivo 'pessoas.txt' com linhas no formato "nome:idade:altura", use sed para trocar a ordem para "altura:nome:idade".
- Use sed para inserir a linha "" antes da primeira linha que contém "" em um arquivo HTML.
- 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).
- 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.
sed -i '1~2d' numeros.txtsed -i 's/\([^:]*\):\([^:]*\):\(.*\)/\3:\1:\2/' pessoas.txtsed -i '//i\' arquivo.htmlsed -i.bak 's/192\.168\.1\./10.0.0./g' rede.confsed -i '/:[7-9]$/a\---' notas.txt