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.