A história do grep
é um tanto antiga. Nascido no UNIX e hoje presente em praticamente todos os sistemas unix-like (Linux, MacOS, FreeBSD, etc).
Portanto, é uma ferramenta que você terá acesso com bastante facilidade. Esta ferramenta serve para buscar um padrão, uma palavra ou texto dentro de arquivos e streams.
Para utilizar este comando, deve-se informar o que deseja-se buscar e onde (sendo o onde opcional dependendo da situação):
grep 'string a ser buscada' arquivo/em_que_deseja-se/buscar/a_string.md
As duas informações mostradas acima são parâmetros, que são separados por espaço.
Caso haja espaço ou outro caracter especial que deva fazer parte do parâmetro, recomenda-se coloca-los entre aspas (como demonstrado acima).
Uma alternativa as aspas pode ser também escapar o espaço ou caracter especial com a barra invertida (\
):
grep string\ a\ ser\ buscada arquivo/em_que_deseja-se/buscar/a_string.md
O segundo parâmetro é opcional devido alguns comportamentos em combinação com o grep
.
Você pode jogar o output de algo para o grep
filtrar:
ps aux | grep node
(ver as linhas dos processos onde contém a string 'node' no meio)
Pode-se passar um conjunto de arquivos para ele buscar, como:
grep asdf *.txt
Ou também poderá buscar recursivamente em todos os arquivos com a flag -r
:
grep -r asdf diretorio/do/projeto
O problema é que nesses casos a gente quer ignorar diretórios como .git
ou node_modules
.
Portanto, podemos informar quais diretórios não queremos:
grep -r diretorio/do/projeto --exclude-dir={.git,node_modules,log,tmp}
Uma flag é uma configuração que é passada para o comando, essas opções se diferenciam de parâmetros por um ou dois sinais de menos (-
ou --
)).
Para programadores a flag -n
é interessante também, pois ela apresenta o número da linha em encontrada dentro do arquivo.
O grep é "case sensitive", ou seja, diferencia caracteres maiúsculos e minúsculos.
Para não diferenciar existe a flag -i
.
A flag -v
(ou --invert-match
) é útil para quando você quer todas as linhas que não coincidem com o padrão buscado, invertendo a busca.
Outra coisa muito bacana são as flags -A
, -B
e -C
Eles recebem um numero que corresponde às linhas após (-A
After), antes (-B
Before) ou tanto antes quanto depois (-C
Context) do que você está buscando.
grep asdf *.txt -C 5
Como o uso padrão do grep
é para encontrar a linha contendo a string buscada, o comando normalmente retorna a linha inteira destacando a parte buscada.
Porém é possível retornar somente o padrão buscado, o que faz sentido em casos de busca por regex onde a intenção é encontrar este padrão para usa-lo em algum outro local.
Para isso existe a flag -o
(ou --only-matching
).
ls -l jars/*.jar | grep -Eo '([0-9]+)\.([0-9]+)\.([0-9]+)(?:\.(R[0-9]+))?')
(exemplo buscando a versão definida no nome de algum arquivo jar
no padrão 11.22.33.R44
)
Note que caso o comando grep
não encontre qualquer resultado o retorno será um erro, permitindo assim utilza-lo para operações lógicas que só devem ser executadas caso o grep
encontre algo:
grep 'padrão' arquivo.txt && echo 'encontrou' || echo 'não encontrou'
Resumindo, se você precisa buscar por uma string dentro de arquivos, o grep
dá conta do recado.
Qualquer dúvida consulte a ajuda do comando (grep --help
) ou o manual (man grep
).
Atualmente existem alternativas com melhor perfomance em relação às buscas e opções:
ack
(beyondgrep) é quem procurou reinventar ogrep
, sendo recursivo por padrão e evitando diretórios dos controladores de versão (como o.git
);ag
(the silver searcher) veio após oack
, mas é facilmente instalável nos servidores, como o CentOS, onde basta instalar usando oyum
pelo nomethe_silver_searcher
;rg
(ripgrep) é o mais novo entre estes, feito em rust e é mais o rápido. Prometendo um nivel de compatibilidade tanto comgrep
quanto com oag
.