sed - alguns exemplos de uso do sed e indicações de tutoriais.

Atualizado em: 31/08/2006



Sobre este documento

linhas de comando e scripts com uso do sed na edição de arquivos textos ou dados passados pelo pipe |.

O que significa sed?

sed é uma linguagem com muitas funcionalidades, excelente na manipulação de strings e arquivo texto, muito útil na linha de comando e scripts, também em combinação com outros aplicativos como cat, ls e etc...

Digite na caixa de pesquisa do www.google.com.br, define:sed não entendeu porque está em ingles? então use o próprio google na tradução, copie a URL atual, no final da página, clique em "Ferramentas de idiomas", cole o endereço, clique em "traduzir", ou acesse diretamente o tradutor em:
http://translate.google.com/translate_t
CTRL+T abre outra aba no browser pra colar a URL que deseja traduzir.

Já que está procurando no google, aproveite e faça a pesquisa, coloque o termo que procure e acrescente
   +sed ~linux, exemplos:
   apagar linha +sed ~linux
   trocar palavra +sed ~linux
   Re: sed ~linux
   sed ~linux
   how to sed ~linux
  
Use e abuse da criatividade, tente com outras variações.

Caso não encontre em sua intalação, use o gerenciador de pacotes e procure "sed"

Depois de instalado consulte a página do manual

man sed

Ver a versão do sed

sed -V

sed --version

substituir palavra dentro de arquivo

trocar, substituir palavra ou frase dentro de um arquivo.

Normalmente se usa como delimitador a "/" barra normal e a barra invertida "\" pra indicar que o proximo caracter é um simbolo.

Também pode usar como delimitador a "|".

sed = Stream Editor.

sed é uma ferramenta poderosa pra manipular arquivos, muito útil e pratica pra utilizar em scripts ou linha de comando sem precisar de usar um editor de texto abrir o arquivo, alterar e salvar.

Com o sed altera arquivos como se faz com o editor de texto, com a diferença que faz isto em linha de comando sem o trabalho de abrir o arquivo no editor de texto, exemplo de linha de comando para troca de palavra em todo o documento.

  sed "s/stringoriginal/stringtroca/g" arquivooriginal > arquivotroca
       |     |             |        |      |              |
       |     |             |        |      |              |_arquivo modificado
       |     |             |        |      |_ arquivo original permanece inalterado
       |     |             |        |_ aplicar em todas ocorrencias do arquivo
       |     |             |__ nova palavra ou frase que substituirá stringoriginal
       |     |___palavra o frase a ser substituida 
       |____ s = substituir

Caracteres especiais requer uma \ antes do simbolo para não ser interpretado pelo shell, exemplo na troca de todos os .(ponto) por _(underline).

sed "s/\./_/g" arquivooriginal > arquivotroca

Exemplo com barra normal "/" na frase que quer trocar, neste exemplo a linha original no squid.conf;

#acl our_networks src 192.168.1.0/24 192.168.2.0/24

Remover o comentário para ficar assim;

acl our_networks src 192.168.1.0/24 192.168.2.0/24

Colar a linha abaixo no console para fazer a troca, observer que é uma única linha e tem a "\" antes de cada ponto e também antes de cada barra normal indicando que o caracter seguinte deve ser mantido, escapando com \ para não serem interpretados nem não confundir o caracter seguinte com parametros do sed.

  sed -i "s/#acl our_networks src 192\.168\.1\.0\/24 192\.168\.2\.0\/24/acl our_networks src 192\.168\.1\.0\/24 192\.168\.2\.0\/24/g" /etc/squid/squid.conf

Trocar o delimitador, usando como delimitador "|', não precisa da "\" (escapar) antes da "/" veja o resultado para alterar zago por backup/docs no arquivo contendo estas linhas.

  /home/zago/guiaz/
  /home/zago/evolution/
  /home/zago/doc/

sed -e "s|/zago|/backup/docs|" /tmp/teste/backup.sh

Não precisou da \ antes de cada / porque usou outro delimitador, retorna.

  /home/backup/docs/guiaz/
  /home/backup/docs/evolution/
  /home/backup/docs/doc/

Com -e pode incluir expressções como final de linha $, inicio de linha ^ e etc..

Redirecinar a saida para outro arquivo como nos exemplos acima ou com a diretiva -i (in place) para alterar no proprio arquivo.

sed -i "s/stringoriginal/stringtroca/g" arquivo

Evite acidentes, procure redirecionar a saida para outro arquivo ou faça copia antes de aplicar as alterações.

Exemplo com o texto de arquivo.txt

cat arquivo.txt

Neste arquivo tem zago, com o comando sed todas as ocorrencias da palavra zago serão modificadas pra Antonio Francisco Zago, compare os dois arquivos.

sed "s/zago/Antonio Francisco Zago/g" arquivo.txt > arquivomodificado.txt

cat arquivomodificado.txt

Neste arquivo tem Antonio Francisco Zago, com o comando sed todas as ocorrencias da palavra Antonio Francisco Zago serão modificadas pra Antonio Francisco Zago, compare os dois arquivos.

No exemplo acima o sed modificou o conteúdo do arquivo, onde encontrou a palavra "zago" fez a substituição por "Antonio Francisco Zago" sem precisar usar um editor de texto para abrir o arquivo fazer a troca e salvar, em uma única linha de comando o sed executou esta tarefa em todo o arquivo.

Remover palavras ou strings de um documento.

sed "s/zago//g" arquivo.txt > arquivomodificado.txt

cat arquivomodificado.txt

Neste arquivo tem o nome , com o comando sed todas as ocorrencias da palavra serão modificadas para Antonio Francisco Zago, compare os dois arquivos.

No exemplo acima não indica nova string, está vazia e portanto a palavra "zago" foi removida, substituida por um campo vazio, veja que também é case sensitive, não modificou Zago com Z maiusculo.

Aplicar determinado comando em todos arquivos de um diretório.

Nestes casos o melhor é montar um script, quando todos tem a mesma terminação ou nomes que permite selecionar com curinga no nome, exemplo para aplicar em todos arquivos .txt

sed -i 's/stringoriginal/stringtroca/g' *.txt

sed -i "s/stringoriginal/stringtroca/g" *.txt

Apagar, remover a string encontrada.

sed -i "s/stringoriginal//g" *.txt

Pegar somente palavras separadas por espaços, use a barra para escapar, indicar um espaço, neste exemplo abaixo tem a \ mais espaço antes e depois de string, ou \s (barra mais espaço ou barra mais a letra s). Neste caso procura pela string entre espaços.

sed 's/\ string\ //g'

sed 's/\ stringvelha\ /\ stringnova\ /g'

sed 's/\sstring\s//g'

Veja alguns resultados, para trocar basta incluir a novastrint entre as duas barras "//"no final do comando, no exemplo abaixo remove porque não informou a string de troca.

  echo "Antonio Francisco Zago" | sed 's/\ cisco\ //g'
  Antonio Francisco Zago
  
  echo "Antonio Francisco Zago" | sed 's/cisco//g'
  Antonio Fran Zago
  
  echo "Antonio Francisco Zago" | sed 's/\ Francisco\ //g'
  AntonioZago
  
  echo "Antonio Francisco Zago" | sed 's/\sFrancisco\s//g'
  AntonioZago
  
  echo "Antonio Francisco Zago" | sed 's/\ Francisco\ /\ troca\ /g'
  Antonio troca Zago

Combinar palavra com inicio ou final de linha

^ indica inicia de linha ^palavra trata somente palavra no inicio da linha, ignora a mesma palavra nas demais partes da linha.

$ indica final de linha palavra$ trata somente palavra no final da linha, ignora a mesma palavra nas demais partes da linha.

Incluir no inicio de todas as linhas do documento

  sed 's/^/texto adicionado/'
  
  sed -i 's/^/texto adicionado/' meuarq.txt
  
  Incluir um TAB para manter o formato na conversão em HTML pelo txt2tags
  
  sed -i 's/^/\t/' meuarq.txt
  
  Ou para manter como item, acrescentar dois pontos mais um espaço no inicio
  de cada linha.
  
  sed -i 's/^/  /' meuarq.txt

Inserir comentário (#) somente nas linhas que inciam com /home/zago

sed -r 's|(^/home/zago)|#\1|g' arquivo.txt

  /home/backup
  /home/backup/home/zago
  #/home/zago/guiaz/
  #/home/zago/doc/
  /etc/

onde \1 mantém a string de procura, sem \1 faz a troca ou precisa repetir a string de procura, comandos sem \1 e equivalentes.

sed -r 's|(^/home/zago)|#/home/zago|g' arquivo.txt

sed -r 's|^/home/zago|#/home/zago|g' arquivo.txt

editar linha especifica do texto

Linha de comando para alterar o conteúdo da terceira linha para 1, aplico esta linha para alterar de 5 para 1 o numero do CD na criação do DVD do SUSE.

  sed -i "3s/^./1/" /tmp/sl101dvd/media.1/media
       |  || |  |           |              |_arquivo que vai aplicar a modificação
       |  || |  |           |_caminho do arquivo a ser modificado
       |  || |  |_ alteração a ser efetuada, novo caracter ou conteúdo da linha
       |  || |_inicio da linha
       |  ||__ s = substituir 
       |  |___3 indica a linha para aplicar alteração, somente esta será afetada
       |____aplicar alteração no próprio arquivo

Alterar somente em linhas com determinada palavra, trocar a palavra velha por nova somente nas linhas que contém a palavra estado.

sed -i '/estado/s/velha/nova/g' arquivo.txt

Trocar ponto por espaço no nome de arquivo.

Observe o uso do sed no script abaixo, a linha;

  arqespac=`echo $i | sed 's:\.: :g'`

echo passa o nome do arquivo em $1, sed troca todos os ponto no nome do arquivo por espaço, na linha seguinte awk pega a primeira coluna, awd usa o espaço como separador de colunas, ou seja, pega a parte do nome que vem antes do primeiro ponto ignorando o resto do nome, basename também faz esta tarefa, mas não atende ao meu caso porque tenho variação muito grande no nome dos arquivos e preciso somente da parte do nome que vem antes do primeiro ponto, aplico este script para converter páginas do man em HTML

  #!/bin/bash
  for i in *.gz ; do
  #coloque aqui seus comandos
  arqespac=`echo $i | sed 's:\.: :g'`
  nome=`echo $arqespac | awk '{print $1}'`
  man ./$i | man2html -title man\ $nome -topm 5 > $nome.html
  done

Apagar linha

Limpando as linhas em branco com sed, linhas em branco sem espaços, (^$) pega somente as linhas com sinal de fim de linha ($) no inicio da linha (^), ou seja, linha em branco, inicia com final de linha.

sed '/^$/d' squid.conf > squid.conf-sed

sed '/^$/d;' squid.conf > squid.conf-sed

Com espaços na linha em branco

cat arq.txt | sed '/^ *$/d' > arqlimpo.txt

Remover linhas que inicial com tab, utilizo nos resultados do comando diff em duas colunas.

cat /tmp/arqtmp.txt | sed '/^\t/d' > /tmp/arqlimpo.txt

Eliminar a primeira linha do arquivo:

sed 1d teste > testesemlinha1 ou sed -i 1d teste

Eliminar a ultima linha de uma arquivo:

sed '$d' teste

Eliminar as ultimas 9 linhas de uma arquivo:

sed -i -e :a -e '$d;N;2,9ba' -e 'P;D' teste.txt

Esta linha é copia do site do Thbias, no original é pra 10 linhas, aqui modificado pra 9 linhas e acrescentado a diretiva -i para modificar o proprio arquivo.

Com o comando acima não exibe no video a ultima linha, para salvar a alterarção, grave o resultado em outro arquivo ex:

sed '$d' teste > testesemultimalinha

Ou para modificar o proprio arquivo use -i, exemplo:

sed -i '$d' teste

Remover uma faixa de linhas, por exemplo da 2 até a 10 e salvar em outro arquivo:

sed -e '2,10d' teste > testenovo

Remover no proprio arquivo da linha 1 até a 22

sed -i '1,22d' teste

Apagar todas as linhas com determinada string:

    sed -i '/As partes desta mensagem/Id' texto.txt
    sed -i '/sexta/Id' texto.txt

Remover linha que inicia com IP 192.168.1.205, utilizo para remover chave de IP que foi moficado no arquivo ~/.ssh/known_hosts

sed -i '/^192.168.1.205/d' ~/.ssh/known_hosts

Faça testes com copia do arquivo em /tmp

sed -i '/^192.168.1.205/d' /tmp/known_hosts

Em minhas instalações de testes isto é repetitivo, para não ficar repetindo a digitação, coloquei no inicio do .bash_history, outra opção que utilizo, criar script e passar o IP na linha de comando, script que utilizo em minhas instalações.

cat /usr/bin/zzsedip

  #!/bin/bash
  sed -i "/^$1/d" ~/.ssh/known_hosts

Com este script basta passar o IP na linha de comando, digitar zzse e tecla tab para completar, depois tecle um espaço e IP que deseja remover

zzsedip 192.168.1.205

Agora é só voltar com as setas até a linha que deu erro e dar enter para criar nova chave e completar a conexão...

aplicar diversos comandos sed no mesmo arquivo

Executar uma sequencia de comandos nos arquivos listados em arqlista, não use ponto ou caracteres especiais no nome deste arquivo, execute o script dentro do diretório onde estão os arquivos a serem modificados, este script é uma versão simplificada para limpar arquivos com download de messagens da lista de shell-script no yahoo, são arquivos pequenos e não tive preocupação com velocidade e outros detalhes, somente remover cabeçalhos e rodapé dos textos, funciona!.

  #!/bin/bash
  for i in $( cat arqlista );do
    # exibir o nome do arquivo sendo processado
     echo $i
    # apagar da linha 1 até a 22
    sed -i '1,22d' "$i"
    # depois apaga a linha 2 e 3
    sed -i '2,3d' "$i"
    # apagar todas as linhas que contem "As partes desta mensagem"
    sed -i '/As partes desta mensagem/Id' "$i"
    # apagar as ultimas 9 linhas
    sed -i -e :a -e '$d;N;2,9ba' -e 'P;D' "$i"
  done

Exibir o nome do arquivo sendo processado, acrescente esta linha

echo $i

find + sed

Pegar somente o nome de arquivos sem a extensão, exemplo de como procurar com find pelos arquivos .txt e retornar o nome sem a extensão.

  find /tmp/guiaz -name "*.txt" -exec basename {} \; | sed s/"\.txt"//g

basename também faz esta função, man basename

Varios exemplos com a mesma finalidade, alterar string em arquivos.

Dicas-l alterou o dominio, trocou unicamp por com, tenho muitas indicações e algumas copias de mensagens com o endereço antigo, no inicio solicitei ao Rubens para corrigir o endereço e fui prontamente atendido, depois constatei que ocorria em todos endereços, a linha de comando abaixo alterou todos arquivos no FAQ.

  Mostrando o resultado antes de alterar.
  grep "Dicas-L.unicamp.br/" -r /home/zago/guiaz/
  
  Contando as ocorrencias
  grep "Dicas-L.unicamp.br/" -r /home/zago/guiaz/ | wc -l
  538
  
  Localizar e substituir em todos arquivos
  
  find /home/zago/guiaz -name "*.*" -exec sed -i s/"Dicas-L.unicamp.br"/Dicas-l.com.br/g {} \;
  

Detalhe, alterou estatus de todos arquivos para modificados, até mesmo os que não teve alteração, como tenho um script que atualiza o site com os arquivos modificados nas ultimas 24 horas, isto forçou upload de todos arquivos para o site, quado for o caso, considere criar script para detectar com grep quais arquivos deve aplicar o sed.

Depois da alteração ainda restou endereços com "dicas-l.unicamp.br", resolvi fazer de outra forma, com sed acessando e alterando somente os arquivos com a expressão de procura.

  #!/bin/bash
  grep "dicas-l.unicamp.br/" -r /home/zago/guiaz/ | cut -d":" -f1 | sort -u > /tmp/altera.txt
  for i in `cat /tmp/altera.txt`
  do
     # testar para ver se está mostrando os arquivos corretos, 
     # quando OK remova o comentário da linha do sed para alterar
      echo $i
  #    sed -i s/"dicas-l.unicamp.br"/dicas-l.com.br/g $i
  done

Conferir se o numero de arquivos alterados coincide com a listagem do arquivo, compare a contagem.

  find /home/zago/guiaz -type f -mmin -3 | wc -l
  80
  cat /tmp/altera.txt | wc -l
  80

Trocar @ por # em e-mail nas mensagens do FAQ

Recebi esta dica de Tulio Miranda Barros <tmbarros # myrealbox.com>

for i in * ; do mv $i 0 ; sed 's/@/#/g' 0 > $i ; rm 0 ; done

Achei melhor não executar esta linha porque altera todos os arquivos, inclusive o @ usando em outros locais como arquivos de configuração, coloquei um aviso na página inicial (menu.html) para alterar somente de quem solicitar.

Por enquanto precisa editar o script para alterar e-mail ( em 3 posições), na troca pode informa ( at ), ou simbolos como ( # ), com espaço ou sem. Para uso eventual está bom, mas tem como melhorar e passar os dados por parametro.

Exemplo para trocar (@) por ( # ) de todos e-mail de zagolinux@gmail.com

  #!/bin/bash
  grep -r zagolinux@uol.com.br /tmp/guiaz/ | cut -d":" -f1 | sort -u > /tmp/altera.txt
  for i in `cat /tmp/altera.txt`
  do
     # faça testes e backup antes de qualquer alteração.
     sed -i s/zagolinux@uol.com.br/zagolinux\ \#\ uol.com.br/g $i
  done

antes e depois

zagolinux@gmail.com

zagolinux # gmail.com

exemplos em uma linha

Uma maneira prática, usar seu editor de texto para alterar a linha de comando, copiar e colar no console, quando vai executar uma única vez, torna mais rápido e prático que criar script, pode quebrar a linha com barra invertida \ ou juntar tudo e usar ; para indicar nova linha, este exemplo pode copiar e colar todas as linhas no console.

  for i in `cat /tmp/altera.txt`
  do
      echo $i
      sed -i s/"dicas-l.unicamp.br"/dicas-l.com.br/g $i
  done
  
  depois de colar mostra estas linhas no console, basta um enter para executar.
  
  for i in `cat /tmp/altera.txt`
  > do
  >     echo $i
  >     sed -i s/"dicas-l.unicamp.br"/dicas-l.com.br/g $i
  > done

Ou use ; para indicar próxima linha, assim agrupa todos os comandos em um únia linha como esta.

for i in `cat /tmp/altera.txt`; do echo $i; sed -i s/"dicas-l.unicamp.br"/dicas-l.com.br/g $i; done

Outros exemplos para aplicar o sed e fazer a mesma alteração em arquivos do diretório corrente, observe o primeiro exemplo a seguir (*.txt) pegando somente esta terminação e o segundo pegando tudo (ls). Não desce nos sub-diretórios, afeta somente arquivos dentro do diretório corrente, no exemplo anterior com find procura e altera também nos sub-diretórios.

for i in *.txt; do cat $i | sed 's/dicas-l.unicamp.br/dicas-l.com.br/g' > /tmp/teste/$i.tmp; done

for i in `ls`; do cat $i | sed 's/dicas-l.unicamp.br/dicas-l.com.br/g' > /tmp/teste/$i.tmp; done

Procura por (Dicas-L.unicamp.) e troca o (unicamp) por (com) altera somente quando unicamp for precedido da empressão entre parenteses (Dicas-L.), o ponto foi usado para não pegar outras expressões, a barra antes do ponto é para tratar como caractere do texto, escapar da interpretação dele como ponto na expressão.

for i in *.txt; do sed -ri 's/(Dicas-L\.)unicamp\./\1com\./g' $i; done

Outros exemplos

alterar com tr

tr . _ < arquivo

tutoriais e scripts especificos

sed - Apagando colunas em um texto
http://www.dicas-l.com.br/dicas-l/20000926.php

Tutoriais, sites e documentação sobre sed

Lista de discussão especifica sobre sed
http://br.groups.yahoo.com/group/sed-br/
Página do Aurelio - Excelente tutorial sed - muita documentação e scripts, exemplos pronto pra copiar e colar, diversos scripts e tarefas.
http://aurelio.net/sed/sed-HOWTO/
Download do livro - Dominando o SED (Documento PDF - 113 páginas - 335KB)
http://aurelio.net/sed/livro/
Sobre a lista : Documentação : Scripts sed : Threads Interessantes
Página do Thobias - sed - muita documentação e scripts, muitos exemplos, pronto para copiar e colar.
http://www.thobias.org/sed/index.html
http://www.thobias.org/doc/sosed.html

scripts tutorials seders ssed links, muita documentação, FAQ, dicas e etc...
http://sed.sourceforge.net/grabbag/

Indicações

sed - FAQ com mensagens da Linux-br
http://www.zago.eti.br/sed.txt

Página principal sobre script em geral (FAQ)
http://www.zago.eti.br/script/A-menu-scripts.html

Página principal deste site (FAQ)
http://www.zago.eti.br/menu.html