Get your own free workspace
View
 

sed

Page history last edited by PBworks 4 years, 6 months ago


Introdução

O SED é um editor de Stream. Pode editar de forma não interativa, centenas ou milhares de arquivos sem a intervenção do usuário. No final do documento cito as fontes de onde tirei alguns exemplos

 

Legenda dos comandos copiada do sed-howto

fonte: http://aurelio.net/sed/sed-HOWTO/sed-HOWTO-4.html

Legenda:

[ARQUIVO]       arquivo ou fluxo de texto (via pipe) original a ser modificado
[TEXTO]         trecho de texto. pode ser uma palavra, uma linha,
                várias separadas por n, ou mesmo um vazio.
[PADRÃO]        [TEXTO] contido no ESPAÇO PADRÃO


=       imprime o número da linha atual do [ARQUIVO]
#       inicia um comentário
!       inverte a lógica do comando
;       separador de comandos
,       separador de faixas de endereço
{       início de bloco de comandos
}       fim de bloco de comandos

s       substitui um trecho de texto por outro
y       traduz um caractere por outro

i       insere um texto antes da linha atual 
c       troca a linha atual por um texto
a       anexa um texto após a linha atual

g       restaura o [TEXTO] contido no ESPAÇO RESERVA (sobrescrevendo)
G       restaura o [TEXTO] contido no ESPAÇO RESERVA (anexando)
h       guarda o [PADRÃO] no ESPAÇO RESERVA (sobrescrevendo)
H       guarda o [PADRÃO] no ESPAÇO RESERVA (anexando)
x       troca os conteúdos dos ESPAÇO PADRÃO e RESERVA

p       imprime o [PADRÃO]
P       imprime a primeira linha do [PADRÃO]
l       imprime o [PADRÃO] mostrando caracteres brancos

r       inclui conteúdo de um arquivo antes da linha atual
w       grava o [PADRÃO] num arquivo

:       define uma marcação
b       pula até uma marcação 
t       pula até uma marcação, se o último s/// funcionou (condicional)

d       apaga o [PADRÃO]
D       apaga a primeira linha do [PADRÃO]
n       vai para a próxima linha
N       anexa a próxima linha no [PADRÃO]
q       finaliza o sed imediatamente

 

alterações sem arquivos temporários

Colaboração: Rodrigo Bernarndo Pimentel

Fonte: http://www.dicas-l.com.br/dicas-l/20041102.php

 

O modo mais comum de se utilizar o sed, quando se desejam fazer alterações em um arquivo, é jogar as alterações em um arquivo temporário (para evitar perda do arquivo), depois mover este para o arquivo original:

 

sed 's/foo/bar/g' arquivo > arquivo.tmp && mv arquivo.tmp arquivo

 

Esta forma é inclusive usada com freqüência nas mensagens veiculadas na dicas-l.

 

No entanto, desde a versão 3.95 (pelo que pude verificar), existe a opção "--in-place" (ou "-i"), que permite a edição direta do arquivo:

 

sed -i 's/foo/bar/g' arquivo

 

Laço para substituição com o sed

for i in $(ls *.txt); {
  sed -i 's/estudo/teste/g' "$i"
}

Após um tempo usando o sed observei que poderia fazer simplesmente assim:

  sed -i 's/estudo/teste/g' *.txt

 

Pode-se também especificar um sufixo para o "-i", de forma que o arquivo original seja copiado para o nome original, acrescentado do sufixo, antes de ser alterado, criando, na prática, um arquivo de backup:

 

sed -i.bak 's/foo/bar/g' arquivo

 

Isto altera "arquivo" (todas as ocorrências de "foo" são substituídas por "bar"), criando "arquivo.bak" com o conteúdo original de "arquivo" (antes da substituição).

 

Notas: O sufixo deve estar junto ao "-i", não pode ser separado por espaços, como normalmente é permitido em argumentos de linha de comando. Se for utilizado o formato longo, o formato é "--in-place=sufixo".

 

Substituir 192.168.5.20 por 192.168.100.10 em todos os arquivos

 

for i in *; do

sed -i 's/192.168.5.20/192.168.100.10/' $i;

done

 

O parâmetro '-n' diz ao sed para só imprimir as linhas indicadas no parâmetro 'p'

sed -n 5p texto.txt

sed '5d' texto.txt

 

Para imprimir a linha 1234 faça:

sed -n 1234p arquivo

 

Agrupando comandos

  sed '/couve/{ p; p; p; }' verduras.txt

 

Ignorando maiúsculas e minúsculas

no sed à partir da versão 3.01-beta1(*) você pode fazer:

   sed -i '/palavra/Id' arquivo

 

Apagar simbolos de final de linha do Windows

   sed -i 's/x0D$//' *.txt

 

Endereçamento

Mas também poderia ser uma linha que tivesse uma palavra qualquer:

prompt$ sed '/estorvo/d' texto.txt

sed '5,10d' texto.txt

sed '5,/estorvo/d' texto.txt

 

Apague da linha 10 até o final do texto $

sed '10,$d' texto.txt

sed '/estorvo/,+3d' texto.txt

sed '/^$/q' pare na primeira linha em branco que achar

sed '1,10!d' NÃO apague da linha 1 até a 10

sed -n '11,$!p' NÃO imprima da linha 11 até o final

 

Apagar a primeira e a última linha

sed -i '1d;$d' arquivo

 

Mostrar da linha 20 em diante do /etc/passwd

   sed -e '1,20d' /etc/passwd | less
   cat -n /etc/passwd | sed  '1,20d' | less

!Substituições

sed 's/isso/aquilo/' texto.txt

 

Mostrar um arquivo sem comentários tipo o lilo.conf

"Endereços de expressão regular sempre estão entre barras"

sed -e '/^#/d' /etc/lilo.conf | less

 

Retirar linhas em branco

sed '/^$/d'

 

Retira linhas em branco excessivas

sed '/./,/^$/!d'

 

Imprimir somente a linha N

OBS: troque o número 2 para a linha que você quiser

 

sed '2!d'

Imprimir somente entre linha N e M

sed '4,6!d'

 

Mostra quantidade de linhas

sed -n $= arquivo

 

Inserir texto no final do arquivo

 

$ final do arquivo

a append, ou seja, adicione

sed -i '$atexto a ser inserido' *.txt

 

Substituir uma string por outra somente entre determinadas linhas

sed '3,6s/dia/noite/'

Imprimir linhas que contém uma ou outra string

OBS: imprime linhas que contém a string 'segundo' ou 'quarto'

  sed '/segundo|quarto/!d'

Um problema que tentei por muito tempo achar uma solução

leve: Fazer buscas dentro de arquivos odt, que são xml

compactado...

 

  descompacte o odt...

  unzip texto.odt 
  cat content.xml | sed 's/<[^>]*>//g' | egrep $busca

Deixando somente as tags html

echo "<td>testando</td>"|sed -n 's@(<.*>).*(<.*>)@12@p'

 

Tirando espaços a mais

  sed 's/ +/ /g' arquivo_cheio_de_espacos

  ou

  sed 's/s+/ /' arquivo_cheio_de_espacos  

Procurando um padrão e imprimindo as duas próximas linhas

sed -n '/padrão/{N;N;p;}' arquivo.txt

Procura por padrão, onde achar junta as duas próximas linhas e
imprime.



Substituições complexas

Para substituir bgcolor="#white" por bgcolor="#eeeeee" em vários arquivos html


  sed -i 's/bgcolor="#white"/bgcolor="#eeeeee"/' *.html



Deletando linhas em branco consecutivas e colocando só uma
    sed '$!N; /^(.*)n1$/!P; D'


 

Substituindo texto em várias linhas

  sed -i 's/palavra/,/expressão/c 
  texto a ser colocado no lugar' arquivo

 

Convertendo decimais apra romanos

/[0-9]*[5-9]...$/q
s/1...$/M&/;s/2...$/MM&/;s/3...$/MMM&/;s/4...$/MMMM&/
s/6..$/DC&/;s/7..$/DCC&/;s/8..$/DCCC&/;s/9..$/CM&/
s/1..$/C&/;s/2..$/CC&/;s/3..$/CCC&/;s/4..$/CD&/;s/5..$/D&/
s/6.$/KX&/;s/7.$/LXX&/;s/8.$/LXXX&/;s/9.$/XC&/
s/1.$/X&/;s/2.$/XX&/;s/3.$/XXX&/;s/4.$/XL&/;s/5.$/L&/
s/1$/I/;s/2$/II/;s/3$/III/;s/4$/IV/;s/5$/V/
s/6$/VI/;s/7$/VII/;s/8$/VIII/;s/9$/IX/
s/[0-9]//g

 

retirando comentários e linhas duplicadas de um arquivo

  cat /etc/lilo.conf | grep -v '^#' | sed '$!N; /^(.*)n1$/!P; D'

  são três comandos encadeados, o cat que lê o arquivo, o grep com opção -v que 
  descarta as linhas que não começam com "#" e o se que tira as linhas duplicadas
  

 

Mais exemplos

Examples of sed operators

Notation Effect
8d Delete 8th line of input.
/^$/d Delete all blank lines.
1,/^$/d Delete from beginning of input up to, and including first blank line.
/Jones/p Print only lines containing "Jones" (with -n option).
s/Windows/Linux/ Substitute "Linux" for first instance of "Windows" found in each input line.
s/BSOD/stability/g Substitute "stability" for every instance of "BSOD" found in each input line.
s/ *$// Delete all spaces at the end of every line.
s/00*/0/g Compress all consecutive sequences of zeroes into a single zero.
/GUI/d Delete all lines containing "GUI".
s/GUI//g Delete all instances of "GUI", leaving the remainder of each line intact.

 

Outra dica

fonte: http://br.groups.yahoo.com/group/sed-br/message/3865

===================================
  Dicas retiradas da lista sed
===================================

On Thu, Jul 20, 2006 at 02:37:52PM -0300, Fernando Zank wrote:
Quem poder ajudar agradeço

Tenho um arquivo testesed

$cat testesed
UC-3.1.1
UC-3.1.11
UC-3.1.13
UC-3.1.15

pretendendo trocar todos números para terem 2 niveis
ex: UC-3.1.7 = UC-03.01.07
UC-3.1.10 = UC-03.01.10

mas to com problema nos casos com números de 2 dígitos:

meu sed e a saída
cat testesed | sed "s/([^0-9])([0-9])/102/g"UC-03.01.01
UC-03.01.011
UC-03.01.013
UC-03.01.015

=============
  Solução
=============
sed ':a s/(b)([0-9])(b)/1023/g;t a'

Essa expressão inclusive funciona para mais "casas":

$ echo UC-3.1.11.1.3.2 | sed ':a s/(b)([0-9])(b)/1023/g;t a'
UC-03.01.11.01.03.02

Espero que isso te ajude.

Truques utilizados:
- Loop (:a , t a)
- Casar beirada de palavra (b)

O motivo para usar o loop e não apenas o modificador g (s///g) fica como
um exercício para o leitor. (Dica: funciona sem incluir o "g", que eu usei,
mas com o "g" fica mais rápido. Não que esta diferença de tempo seja
perceptível).

 

Usando variáveis para alterar arquivos com sed, *grep e outros

Autor: Davidson Rodrigues Paulo

Data: 21/04/2006

Fonte: http://www.vivaolinux.com.br/dicas/impressora.php?codigo=6881

 

solução ideal

use o parâmetro "-i" do sed, assim você não precisa fazer firulas (leia o resto pra ver)

sed -i 's/nao/sim/' teste.txt

 

Usando variáveis para alterar arquivos com sed, *grep e outros

 

Quem usa Linux e programa em Shell Script com certeza já precisou fazer alguma alteração num arquivo usando interpretadores de expressões regulares como sed, egrep e outros. Entretanto, esses comandos não possuem a função de aplicar modificações no arquivo de origem (as versões mais recentes do sed possuem essa função) e, em todos os lugares onde eu procurei uma orientação sobre o que fazer, a recomendação era de criar um outro arquivo e então substituir o arquivo antigo pelo outro. Algo assim:

 
  $ sed [comando] [arquivo] > [arquivo].new
  $ mv [arquivo].new [arquivo]

 

Bom, acontece que eu acabei descobrindo um jeito de fazer a mesma coisa sem criar nenhum novo arquivo. Basta usar variáveis de ambiente. Isso mesmo. Veja como poderíamos fazer a mesma coisa acima citada usando essa técnica:

  $ TEXTO=`sed [comando] [arquivo]`
  $ echo "$TEXTO" > [arquivo]

ou 
   
   echo "$(sed 's/nao/sim/' teste.txt)" > teste.txt

A grande vantagem desse método é a maior velocidade que se ganha, já que as variáveis ficam armazenadas em memória, sendo manipuladas muito mais rapidamente do que arquivos armazenados em disco.

 

Você pode ver um exemplo prático de aplicação dessa técnica no script de instalação que eu desenvolvi para o pacote para Slackware do Squid. Esse script atualiza o arquivo /etc/rc.d/rc.M, inserindo uma entrada para a inicialização em tempo de boot do Squid.

 

Eu usei o sed no exemplo, mas poderia ter usado qualquer outro programa. O procedimento é o mesmo para outros comandos.

 

Agradecimentos ao amigo Elias que me apontou uma pequena falha que eu estava cometendo nesse procedimento. Valeu Elias!

 

Conceitos avançados

Veja o manual do Arélio Marinho Jargas:

 

http://www.vivaolinux.com.br/dicas/verDica.php?codigo=6881

 

problema:

entrada:
A
B
A
B
A
B

saida desejada:
B
A
B
A
B
A

eu tive o problema a cima ... e a solucao foi usar o sed ...

$ echo -e "AnBnAnBnAnB"| sed -n 'h;n;G;p'

todavia, as opcoes do sed me pareceram muito obscuras
pois eu nao entendia esse tal de `n` hide e `n` next.

ai eu resolvi dar uma lida, por ai e agora vejo que o sed eh
um cara muito simples ...

E VOU COMPARTILHAR COM VCS ESSAS OBSERVACOES

vejamos:
substituindo as opcoes de linha por um arquivo com as mesmas

'h;n;G;p' virou troca.sed

$ cat troca.sed

h
# esconde a linha no buffer
# buffer <= linha(atual)

n
# proxima linha
# atual++

G
# saida = saida + buffer + linha(atual)

p
# imprima a saida.

Tah sei que parece loucura ...
mas veja dessa forma:

em uma pseudo linguagem ... teriamos

saida = empty
buffer = empty

atual = 1;
while (atual <= NumeroDeLinhasDoPipe) {
buffer = linha(atual)
atual ++
saida = saida + buffer + linha(atual)
atual ++
}
imprima saida

FIM ...

CLARO QUE DA FORMA ABAIXO EH MELHOR .... E CORRETA!!!

while (atual <= NumeroDeLinhasDoPipe) {
buffer = linha(atual)
saida = saida + buffer + linha(atual)
atual +=2
}

vlw

--
[ ]'s
Ivan Carlos Da Silva Lopes

Engenheiro Eletronico e Computacao
UFRJ

 

trocando hexadecimais por ascii

#!/bin/sed -f
# unescape.sed - traduz os escapes hexadecimais para ascii
# fonte: http://br.groups.yahoo.com/group/sed-br/message/217
#
# útil para converter para texto legível por humanos as tripas
# que os navegadores fazem com o conteúdo de formulários
#
# IMPORTANTE! n r t: sed >= 3.02.80
#
# 20000706 <aurelio@...> ** 1a versão

# tem que ser o primeiro para não confundir com + literais
s/+/ /g

# quebra de linha (lynx %0d, netscape %0D)
### 2 linhas seguintes: apenas para sed >= 3.02.80
s/%0[Dd]%0[Aa]/n/g
s/%09/t/g
### 3 linhas seguintes: sed < 3.02.80
#s/%0[Dd]%0[Aa]/
#/g
#s/%09/ /g


# substituições padrão hexa->ascii
s/%21/!/g
s/%22/"/g
s/%23/#/g
s/%24/$/g
s/%26/&/g
s/%27/'/g
s/%28/(/g
s/%29/)/g
s/%2B/+/g
s/%2C/,/g
s/%2F///g
s/%3A/:/g
s/%3B/;/g
s/%3C/</g
s/%3D/=/g
s/%3E/>/g
s/%3F/?/g
s/%5B/[/g
s/%5C/\/g
s/%5D/]/g
s/%5E/^/g
s/%60/`/g
s/%7B/{/g
s/%7C/|/g
s/%7D/}/g
s/%7E/~/g
s/%A1/¡/g
s/%A2/¢/g
s/%A3/£/g
s/%A4/¤/g
s/%A5/¥/g
s/%A6/¦/g
s/%A7/§/g
s/%A8/¨/g
s/%A9/©/g
s/%AA/ª/g
s/%AB/«/g
s/%AC/¬/g
s/%AD/­/g
s/%AE/®/g
s/%AF/¯/g
s/%B0/°/g
s/%B1/±/g
s/%B2/²/g
s/%B3/³/g
s/%B4/´/g
s/%B5/µ/g
s/%B6/¶/g
s/%B7/·/g
s/%B8/¸/g
s/%B9/¹/g
s/%BA/º/g
s/%BB/»/g
s/%BC/¼/g
s/%BD/½/g
s/%BE/¾/g
s/%BF/¿/g
s/%C0/À/g
s/%C1/Á/g
s/%C2/Â/g
s/%C3/Ã/g
s/%C4/Ä/g
s/%C5/Å/g
s/%C6/Æ/g
s/%C7/Ç/g
s/%C8/È/g
s/%C9/É/g
s/%CA/Ê/g
s/%CB/Ë/g
s/%CC/Ì/g
s/%CD/Í/g
s/%CE/Î/g
s/%CF/Ï/g
s/%D0/Ð/g
s/%D1/Ñ/g
s/%D2/Ò/g
s/%D3/Ó/g
s/%D4/Ô/g
s/%D5/Õ/g
s/%D6/Ö/g
s/%D7/×/g
s/%D8/Ø/g
s/%D9/Ù/g
s/%DA/Ú/g
s/%DB/Û/g
s/%DC/Ü/g
s/%DD/Ý/g
s/%DE/Þ/g
s/%DF/ß/g
s/%E0/à/g
s/%E1/á/g
s/%E2/â/g
s/%E3/ã/g
s/%E4/ä/g
s/%E5/å/g
s/%E6/æ/g
s/%E7/ç/g
s/%E8/è/g
s/%E9/é/g
s/%EA/ê/g
s/%EB/ë/g
s/%EC/ì/g
s/%ED/í/g
s/%EE/î/g
s/%EF/ï/g
s/%F0/ð/g
s/%F1/ñ/g
s/%F2/ò/g
s/%F3/ó/g
s/%F4/ô/g
s/%F5/õ/g
s/%F6/ö/g
s/%F7/÷/g
s/%F8/ø/g
s/%F9/ù/g
s/%FA/ú/g
s/%FB/û/g
s/%FC/ü/g
s/%FD/ý/g
s/%FE/þ/g
s/%FF/ÿ/g

# tem que ser o último para não bagunçar os hexadecimais
s/%25/%/g

 

links

 

Referências

Comments (0)

You don't have permission to comment on this page.