O comando SED do Linux

A ferramenta SED, junto ao AWK, são as duas principais linguagens para manipulação de arquivos e streams do Unix/Linux. Ambas possuem vasta abrangência e o que uma não pode fazer, a outra provavelmente o fará. Com o SED é possível substituir e “casar” padrões, sempre por meio de Expressões Regulares, outra grande ferramenta do mundo da Computação. O SED, assim como o AWK, lê um arquivo, linha por linha, e aplica a expressão do parâmetro a cada uma delas. A sintaxe do SED é a seguinte:

sed 'expressão' arquivo

É possível filtrar a saída de outro comando, em vez de filtrar um arquivo, usando pipe. Usarei saídas do comando echo para explicar o sed. SED usa Expressões Regulares (ER’s). Se você não conhece ER’s, sugiro ler o Expressões Regulares – Guia de Consulta Rápida. Também recomendo o livro do mesmo autor do texto citado, Expressões Regulares – Aurélio Marinho Jargas, e Expressões Regulares Cookbook – Soluções Detalhadas Em Oito Linguagens de Programação – Steven Levithan; Jan.

NOTA: O conteúdo deste post foi aprimorado e somado a diversos outros temas ligados à Programação usando Shell Script. Tudo isso resultou no curso “Shell Script Para Programadores“. Conheço melhor o curso neste link.

 

Sumário

1. Substituindo textos: comando s

Sintaxe: s/ER/sub/[modificadores]: Substitui os padrões “casados” em “ER” por “sub”. A utilidade mais conhecida do SED é a substituição de textos. Para isso, usamos o comando “s” do sed:

echo "Tutorial sobre sed: aprenda a trabalhar com sed" | sed 's/sed/awk/'

A saída será: Tutorial sobre awk: aprenda a trabalhar com sed. Note que a última ocorrência de “sed” não foi modificada. Isso porque o sed faz a modificação na primeira ocorrência e, em seguida, já procura pelo padrão na linha seguinte, se houver. Para que o sed execute a ação na linha toda, usamos o modificador “g”:

echo "Tutorial sobre sed: aprenda a trabalhar com sed" | sed 's/sed/awk/g'

Agora a saída é a esperada: Tutorial sobre awk: aprenda a trabalhar com awk. Os modificadores serão abordados com mais detalhes logo mais abaixo. Não percam! =P

1.1. Escapando o delimitador

Como estamos usando a barra (/) como delimitador, se quisermos usar esse caractere na ER ou na substituição, temos de escapá-lo, com barra invertida:

echo "o arquivo /proc/cpuinfo possui informações importantes" | sed 's/\/proc\/cpuinfo/\/etc\/passwd/'

Saída: o arquivo /etc/passwd possui informações importantes

1.2. Usando a expressão casada em ER na substituição

Às vezes queremos acrescentar algo ao texto original. Por isso, é preciso que tenhamos o texto casado na ER. Para isso, usamos o caractere & para nos referirmos à expressão casada pela ER. Suponhamos que queremos colocar todos os caminhos de arquivos entre aspas. Para isso:

echo -e "o arquivo /proc/cpuinfo possui informações importantes \nEste tutorial está em /home/beraldo/tutoriais. Há muitos outros nesse diretório" | sed -r 's/(\/[^ .,]*)+/"&"/'

Saída: o arquivo “/proc/cpuinfo” possui informações importantes Este tutorial está em “/home/beraldo/tutoriais”. Há muitos outros nesse diretório A opção “-r” usa o padrão estendido de expressões regulares – o mesmo usado por “egrep”. Isso possibilita o uso da lista negada.

1.3 Usando “retrovisores” (\1, \2…)

Muitas vezes queremos substituir partes de um texto, mas manter outras. Para isso, podemos usar os “retrovisores”, que inserem na string final os padrões casados na ER inseridos em grupos (( e )). O primeiro grupo casado é referenciado por \1, o segundo, por \2 e assim sucessivamente, até \9. Por exemplo, vamos manter apenas a primeira palavra de cada linha do texto:

echo -e "primeira linha\nsegunda linha\nterceira linha" | sed -r 's/^([a-z]+).*/\1/g'

Importante: Para usar os retrovisores, é necessário usar a opção -r do sed, que ativa o padrão estendido de ERs.

2. Modificadores

 

2.1. Modificador “g”: tratar linha inteira

Já vimos o modificador g anteriormente, que serve para forçar o SED a aplicar a expressão na linha inteira. É possível associar um número ao modificador “g”, para fazer com que o SED atue apenas a partir de uma determinada ocorrência do padrão. Por exemplo, vamos substituir por NULL todas as palavraas do texto:

echo "palavra1 palavra2 palavra3" | sed -r 's/([a-zA-Z0-9]+)/NULL/g'

Vamos supor que gostaríamos de remover todas as ocorrências, exceto a primeira. Para isso executaríamos o sed assim:

echo "palavra1 palavra2 palavra3" | sed -r 's/([a-zA-Z0-9]+)/NULL/2g'

O “2” faz com que a substituição ocorra apenas a partir da segunda ocorrência do padrão.

2.2. Modificador “p”: exibir na tela

Por padrão, o SED imprime na saída padrão todas as linhas lidas – e modificadas. A opção -n impede que o sed faça a impressão das linhas. É nessa situação que o modificador “p” é útil. Quando quisermos imprimir somente as linhas alteradas pelo SED, usaremos o modificador “p”.

echo -e "linha sem números \nLinha com números: 1 2 3 4 5 6 \nLinha com mais números 42 81" | sed -r -n 's/[0-9]+/X/gp'

Serão mostradas apenas as linhas que casaram com o padrão. Como foi possível ver no exemplo acima, é possível misturar os modificadores.


3. Restringindo por linhas

E possível fazer o SED atuar somente num intervalo de linhas. Vamos mostrar os dez primeiros usuários do sistema, listando as dez primeiras linhas do arquivo /etc/passwd.

sed -r -n '1,10 s/([^:]+).*/\1/p' /etc/passwd

Note a opção -n e o modificador “p”, para mostrar somente o padrão casado. É possível usar o caractere $ (cifrão) para se referir à última linha do arquivo:

sed -r -n '1,$ s/([^:]+).*/\1/p' /etc/passwd

 

4. Restringindo por padrões

Além de restringir por número de linhas, podemos restringer por padrão:

echo -e "esta\né\numa\nlinha\nusada\npara\ntestar\no\ncomando\nsed" | sed  -e '/uma/,/comando/s/[ae]/X/g'

 

[cta id=’925′]

5. Remover linha: comando d

O comando “d” do sed remove linhas. Vamos remover as dez primeiraas linhas de /etc/passwd:

sed '1,10 d' /etc/passwd

 

6. Sair: comando q

O comando “q” faz o sed parar após encontrar o padrão Imprime as dez primeiras linhas de /etc/passwd

sed '10 q' /etc/passwd

Para após encontrar um número:

echo -e "sou uma linha\nsou outra linha\nesta linha tem número 1\nesta já não tem número" | sed -r '/[0-9]+/ q'

 

7. Adicionando linha: comando “a”

É possível inserir linha após achar um padrão: Insere linha após uma linha que contenha número

echo -e "sou uma linha\nsou outra linha\nesta linha tem número 1\nesta já não tem número" | sed -r '/[0-9]+/ a Oi. Sou novo aqui'

 

8. Adicionando linha: comando “i”

Quase igual ao comando “a”, mas insere a nova linha antes da linha casada com o padrão Insere linha antes de uma linha que contenha número

echo -e "sou uma linha\nsou outra linha\nesta linha tem número 1\nesta já não tem número" | sed -r '/[0-9]+/ i Oi. Sou novo aqui'

 

9. Mudando uma linha: comando c

Semelhante a “a” e “i”, mas muda a linha que casou com o padrão

echo -e "sou uma linha\nsou outra linha\nesta linha tem número 1\nesta já não tem número" | sed -r '/[0-9]+/ c Fui modificado'

 

10. Dicas de Livros e Cursos

Um excelente eBook, que comtempla o SED e também o AWK (outra excelente linguagem) é o SED And AWK Pocket ReferenceAproveite a versão digital, que pode ser lida em qualquer dispositivo usando o aplicativo Kindle, da Amazon

Para aprender mais sobre Comandos Linux e Shell Script, veja meu curso Shell Script Para Programadores.

The following two tabs change content below.
Graduado em Ciência da Computação, pela Universidade Federal do Paraná (UFPR), é desenvolvedor de software desde 2008, com foco em Desenvolvimento Web com PHP.
  • Pingback: Tweets that mention O comando SED do Linux | Blog do Beraldo -- Topsy.com()

  • Pingback: Curso de Shell Script: Módulo #0 - Comandos Básicos do Linux | Blog do Beraldo()

  • Pingback: Curso de Shell Script: Módulo #0 – Comandos Básicos do Linux | OGordo.com //Um blog de peso()

  • Pingback: Curso de Shell Script: Módulo #0 - Comandos Básicos do Linux | Profissionais TI - Pra quem respira informação()

  • Pingback: Curso de Shell Script: Módulo #0 – Comandos Básicos do Linux | Fedora Dicas()

  • Junior

    Socorro, o tico e o teco estão em conflito.

    Este “1.2” não entra na minha cabeça de jeito nenhum.

    Eu uso nome=`echo “$VAR” | sed -n ‘s/^.*nome=\([^&]*\).*$/\1/p’` para “coletar” as variáveis do método GET mas tento entender com todas as minhas forças mas não consigo.
    Pode me ajudar?

  • Pingback: Confluence()

  • Pingback: Confluence: Qualidade()

  • Pingback: Shell Script e Agendamento de rotinas | Monolito Nimbus()

  • Muito bom este tutorial

  • Denilson Telaroli

    Me ajudou bastante.
    Obrigado.

  • Luciano

    É possível usar o sed para apagar um intervalo de linhas que não necessariamente se inicie na primeira linha?

    Explico: tenho um arquivo com 5220 linhas e preciso somente das que estão no intervalo [820,4200]. Neste caso posso usar o sed duas vezes como abaixo ou não?

    sed ‘1,819 d’ arquivo.txt
    sed ‘4201, 5220 d’ arquivo txt

    Agradeço.

    • Olá, Luciano.

      Se você se interessa por apenas um intervalo de linhas, por que não faz o sed imprimir esse intervalo em vez de remover o que está fora dele?

      Por exemplo:

      Arquivo arq.txt:

      linha 1
      linha 2
      linha 3
      linha 4
      linha 5
      linha 6
      linha 7

      Se só as linhas de 3 a 5 me interessam:

      $ sed -n ‘3,5p’ arq.txt
      linha 3
      linha 4
      linha 5

  • marcio

    Olá, em primeiro lugar parabéns por transmitir essas dicas tão importantes para nós que trabalhamos com linux. uma duvida sabemos que para mudar uma palavra para outra fazemos dessa forma sed ‘s/antigo/novo/g arquivo.TXT minha duvida é a seguinte: não tenho encontrado na internet de modo algum como alterar palavras que contem espaços. por exemplo tenho um arquivo que o conteudo dele contem escrito teste: root
    preciso alterar para teste: usuario1 ou seja quando encontrar a palavra teste: depois do espaço ele muda para usuario1

  • Tiago Alexandre Galera

    Obrigado amigo por seu tutorial me ajudou muito.. Mas preciso de inserir uma variavel dentro do arquivo para eu possa chamar esse arquivo no shell ja modificado, eh possivel?

    • Tiago Alexandre Galera

      Ja consegui, apenas estava faltando colocar ‘$variavel’, de qualquer forma mais uma vez obrigado..

      • Olá.
        Não entendi direito a dúvida. Mas que bom que já resolveu :)

  • Fabrício Abel

    Parabéns pelo artigo!

    Me ajudou muito!