Certo dia, em meu local de trabalho, surgiu a necessidade de realizarmos a troca de certas palavras por outras em todos os
arquivos de um diretório e seus sub-diretórios que contivessem as referidas palavras.
Bom, o que fazer para saber quais
arquivos contém a palavra que quero? "Maravilha, vou usar o grep e beleza!". Pois é, o grep é sim a solução mais lógica para resolver este problema, mas...
Neste mesmo caso que citei, usando "grep -R palavra", a partir do diretório em que eu queria buscar resultou-me em uma saída "grandinha", digamos.
"Ótimo", pensei, "vou jogar a saída em um
arquivo texto e depois analiso o que gerou."
$ grep -R palavra . > arquivo-saida-grep.txt
E o resultado é que o
comando demorou uma eternidade, quase fritou um dos processadores (tá bom, é exagero :)) e me gerou um
arquivo de míseros 15G!
Mas, "não contavam com minha astúcia"! Analisando mais friamente a saída gerada, primeiro pude perceber que o retorno do grep é:
arquivo: linha que o grep achou o que você pediu para procurar
Também notei que, se ouve mais de uma ocorrência de palavra no mesmo arquivo, o
arquivo será listado quantas vezes houverem tais ocorrências.
Bingo! Uns "comandinhos" a mais e matei a charada. ;)
E aí está, sem mais delongas, o
comando para listar todos os
arquivos que contém determinado padrão recursivamente dentro de um diretório:
$ grep -R padrão . 2> /dev/null | cut -f 1 -d ":" | uniq
Onde:
- grep -R padrão . - quer dizer: "Procure pelo padrão padrão em todos os arquivos a partir deste diretório!";
- 2> /dev/null - em caso de erros, não será exibido - se houvesse erro de permissão negada, por exemplo, haveria um falso positivo, pois o diretório onde gerou o erro estaria listado como se houvesse sido encontrado padrão;
- cut -f 1 -d ":" - aqui usamos nosso amigo cut para filtrarmos a saída gerada, obtendo apenas o primeiro campo (-f 1) separado pelo delimitador "dois pontos" (-d ":");
- uniq - por fim, o uniq faz-me o favor de exibir apenas um arquivo por vez, nada de arquivos repetidos na listagem.
Assim eu tenho uma listagem limpa, simples e rápida. Exatamente o que precisava.
Ah, para fazer o replace pode ser utilizado o sed, mas isto já seria assunto para uma outra dica...
Grande abraço,
Xico.