Sed, Grep e afins
Caloni, 2008-03-10 computer blogEsse artigo é resultado de eu ter me matado para conseguir encontrar a forma correta de usar o aplicativo sed para fazer uma filtragem simples nos resultados de uma listagem de arquivos.
Primeiramente, eu gostaria de expressar minha total surpresa ao não conseguir encontrar um guia simples e confiável de uso dessas ferramentas na web. Existem três teorias: ou eu não sei usar as palavras mágicas certas no Google, ou a indexação das páginas realmente importantes sobre o assunto não funcionam com o Google, ou de fato não existe documentação fácil sobre o tema.
Como esta é uma exceção em anos de "googadas", eu fico com a terceira opção.
Existem algumas ferramentas que já salvaram minha vida uma dúzia de vezes e devo admitir que são tão poderosas e flexíveis quanto difíceis de usar:
Essas ferramentas são nativas do ambiente Linux, mas podem ser instaladas no Windows através do Cygwin, do Mingw ou nativamente através das ferramentas GnuWin32.
Update 2026-02-20: desde muitos anos tenho usado de adicionar no path do sistema algumas pastas da instalação do Git. Lá existem todas essas ferramentas e muito mais.
O que eu queria era processar a saída de um programa de forma que eu tivesse a lista de todas as extensões dos arquivos. Por exemplo, para a seguinte entrada:
c:\path\arquivo1.cpp c:\path\arquivo2.h c:\arquivo3.hpp c:\path\path2\arquivo4.cpp
Eu gostaria de uma saída no seguinte formato:
.cpp .h .hpp
Basicamente é isso.
Para filtrar o path do arquivo, e ao mesmo tempo retirar seu nome, podemos usar o seguinte comando (fora outras trilhões de variantes):
programa | sed -e "s/^.*\\//" -e "s/.*\.\(.*\)/\1/"
Após esse processamento, a saída é um monte de extensões vindas de um monte de arquivos:
cpp h cpp h c h cpp h mak vcproj h cpp h cpp h cpp h cpp h c h txt c cpp h mak vcproj cpp h ...
Como podemos ver e é óbvio de imaginar, muitas extensões irão se repetir. Para eliminar as repetições e ordenar a saída da saída corretamente, usamos o comando sort:
programa | sed -e "s/^.*\\//" -e "s/.*\.\(.*\)/\1/" | sort -u
Os caracteres .*[]^$\ dão problemas se usados sem escape no sed, pois fazem parte dos comandos para procurar expressões regulares. Use-os com o caractere de escape `\`.
Obs 2026-02-20: O comando sort do Windows pode entrar em conflito com o sort da GNU. Nesse caso é preciso especificar o path completo do sort correto ou colocar o path das ferramentas GNU com prioridade maior que as do system32, o que eu não recomendo.
Para concatenar comandos no sed, use sempre -e "comando". A ordem de execução dos comandos é a ordem em que eles são inseridos na linha de comando, ou seja, podemos confiar que no segundo comando o primeiro já terá sido executado e assim por diante.
Para fazer o escape das barras do caminho de um arquivo temos que usar o conjunto `\/` (obs.: caminhos em formato Unix). Para evitar esse uso enfadonho podemos substituir o caractere de divisão do comando s colocando-o na frente:
s/path\/muito\/muito\/muito\/longo.cpp/outropath\/muito\/muito\/longo.cpp/s#/path/muito/muito/muito/longo.cpp#/outropath/muito/muito/longo.cpp#
Para agrupar expressõe, use sempre `\(` e `\)`. É o contrário do uso dos caracteres especiais. Coisas de Unix.