Nese post, intitulado “Sed: Tutorial de Inicialização e Mostrando Exemplos” é baseado no artigo de Bruce Barnett que encontra-se no em grymoire.com.

Introdução ao Sed
Sed é o melhor editor de stream. Se isso soa estranho, imagine um riacho fluindo por um cano transparente. sed é um utilitário maravilhoso. Infelizmente, a maioria das pessoas nunca aprende seu verdadeiro poder. A linguagem é muito simples, mas há documentação difícil de entender em diversos locais da internet.
Veja também: Linux: Manipulando texto na linha de comando com sed
O comando essencial: s para substituição
O Sed tem vários comandos, mas a maioria das pessoas aprende apenas o comando substituto: s. O comando de substituição altera todas as ocorrências de expressão regular para um novo valor.
Veja esse texto
maria@ti:~$ cat texto.txt os jogos são bons jogos são para a vida toda jogos para durar para sempre jogos são jogos quando esses jogos são ótimos
Vamos alterar a palavra jogos para games
maria@ti:~$ sed 's/jogos/games/' texto.txt os games são bons games são para a vida toda games para durar para sempre games são jogos quando esses jogos são ótimos
Esse resultado fica apenas na tela, não é saldo em local nenhum. Podemos gerar um novo arquivo com esse resultado usando o redirecionador >
maria@ti:~$ sed 's/jogos/games/' texto.txt > arquivoNovo.txt
Ou ainda podemos alterar o próprio arquivo texto.txt usando a opção -i de in-place(no local)
maria@ti:~$ sed -i 's/jogos/games/' texto.txt
Podemos usar “-i + nome_qualquer” para gerar um backup. nome_qualquer é qualquer nome que queira colocar 🙂
maria@ti:~$ sed -i.bkp 's/games/jogos/' texto.txt
Vamos listar os arquivos da pasta
maria@ti:~$ ls -l total 28 -rw-rw-r-- 1 maria maria 125 dez 30 09:05 texto.txt -rw-rw-r-- 1 maria maria 125 dez 30 09:04 texto.txt.bkp
uma forma de lidar com exemplos é por médio do comando echo; assim não precisaremos de um arquivo de texto.
maria@ti:~$ echo "o dia está belo(a)" | sed 's/dia/noite/' o noite está belo(a)
Devo enfatizar que o editor sed muda exatamente o que você diz. Então, se você executou
maria@ti:~$ echo "spiderman, man, homem" | sed 's/man/homem/' spiderhomem, man, homem
Outra coisa importante é que sed é orientado por linha.
Se executarmos sed sed ‘s/um/UM/’ no arquivo abaixo
maria@ti:~$ cat numeros.txt um dois três, um dois, um três um dois três quatro três dois cento e um
o resultado será a mudança de um para UM em todas as linhas. A primeira linha contém 3 vezes a palavra um mas somente a primeira ocorrência foi alterada.
maria@ti:~$ sed 's/um/UM/' numeros.txt UM dois três, um dois, um três UM dois três quatro três dois cento e UM
Coloque um g ao final do comando para alterar tudo
maria@ti:~$ sed 's/um/UM/g' numeros.txt UM dois três, UM dois, UM três UM dois três quatro três dois cento e UM
A barra como delimitador no sed
O caractere após o s é o delimitador. Uma barra(/) é usada mais por convenção mesmo, pois é o que os programas ed, more e vi usam. Mas poderia ser qualquer outro caractere no lugar da barra. Mas, e se você desejar alterar um nome de caminho que contém uma barra, digamos /usr/local/bin para /common/bin? você poderá usar a própria outra barra \, a invertida, para tirar o sentido da / Isso acontece porque a barra invertida \ também serve como escape no linux, ou seja, para escapar de alguma coisa ou desviar. Então para tirar o sentido, o papel da barra / no sed usamos /\
's/\/usr\/local\/bin/\/common\/bin/.....'
Coloquei apenas parte do código, mas podemos ver que fica algo muito feio e confuso. É mais fácil de ler se você usar um sublinhado em vez de uma barra como delimitador. Lembrando que o delimitador / pode ser qualquer caractere. Então ficaria assim:
maria@ti:~$ echo "/usr/local/bin/" | sed 's_/usr/local/bin/_/usr/outrapasta/bin/_'
Algumas pessoas usam dois pontos(:) como delimitador
maria@ti:~$ echo "/usr/local/bin/" | sed 's:/usr/local/bin/:/usr/outrapasta/bin/:' /usr/outrapasta/bin/
Obs.: lembre-se de que você precisa usar três delimitadores. Se você obtiver um erro de “comando ‘s’ não finalizado” é porque está faltando um deles.
Usando & como uma String de Combinação(matched)
Às vezes, você deseja procurar um padrão e adicionar alguns caracteres, como parênteses, ao redor ou perto do padrão encontrado. É fácil fazer isso se você estiver procurando por uma string específica:
Vamos usar novamente om texto abaixo como exemplo:
[root@oracle86 ~]# cat numeros.txt UM dois três, UM dois, UM três UM dois três quatro três dois cento e UM
Para colocar um parênteses ao redor da palavra UM. Substituiremos UM por (UM). A solução requer o uso do caractere especial “&” corresponde ao padrão(pattern) encontrado.
[root@oracle86 ~]# sed 's/UM/(&)/g' numeros.txt (UM) dois três, (UM) dois, (UM) três (UM) dois três quatro três dois cento e (UM)
Você também pode dobrar um padrão, por ex. o primeiro número de uma linha:
[root@oracle86 ~]# sed 's/UM/(&) (&)/g' numeros.txt (UM) (UM) dois três, (UM) (UM) dois, (UM) (UM) três (UM) (UM) dois três quatro três dois cento e (UM) (UM)
Você pode estar pensando: “Mas não era só usar sed ‘s/UM/(UM)/’ ????”
Sim, nesse caso realmente. Mas vamos supor esse outro cenário. Tenho que envelopar qualquer número com parênteses. Como não sabemos qual número poderá aparecer em um texto longo podemos usar a expressão regular [0-9]* ou [0-9][0-9]* para pegar qualquer número de 0 a 9. Poderíamos ir aumentando a expressão [0-9][0-9][0-9][0-9][0-9]*
- “[0-9]*” corresponde a zero ou mais números
- “[0-9][0-9]*” corresponde a um ou mais números
Poderíamos usar “[0-9]+” para obtermos o mesmo resultado. Mas o caractere + iria “quebrar” o sed, pois ele é faz parte do que chamamos de expressão regular estendida. Para usar o + podemos usar a opção -r do sed:
Vejamos na prática:
[root@oracle86 ~]# echo "os números 1 é o menor e o 9 é o maior. O 5 é o do meio?" | sed 's/[0-9][0-9]*/(&)/g' os números (1) é o menor e o (9) é o maior. O (5) é o do meio?
como dica, podemos usar [a-z] para caracteres minúsculos ou [A-Z] para combinar(dar match) em letras maiúsculas.
duplicando um valor correspondido:
[root@oracle86 ~]# echo "123 abc" | sed -r 's/[0-9]+/& &/' 123 123 abc
Usando \1 para manter parte do padrão
\1 mantém uma substring dos caracteres correspondidos pela expressão regular. O “\1” é o primeiro padrão lembrado e o “\2” é o segundo padrão lembrado. Sed tem até nove padrões lembrados.
Se você quiser manter a primeira palavra de uma linha e excluir o restante da linha, marque a parte importante com parênteses. Abaixo produzirá “abcd” e excluirá os números:
[root@oracle86 ~]# echo abcd123 | sed 's/\([a-z]*\).*/\1/' abcd