Ferramenta útil para pesquisa em arquivos de texto estruturados por indentação.
Inspirado no ogrep de Matt Brubeck. Esse ogrep é compacto e bonito, mas não cheio de recursos.
Veja também ogrep — porte desta ferramenta escrita em Python (para ser sincero, foi o primeiro).
ogrep
é muito parecido com grep
, ambos podem procurar correspondências e exibir seu contexto. Mas o contexto no grep
é “N linhas antes/depois da correspondência”, e no ogrep
é “as linhas acima correspondem a uma com recuo inferior”.
Deixe-me explicar. Eu uso essa ferramenta principalmente quando trabalho com arquivos de compilação GN, então usarei um arquivo BUILD.gn grande como exemplo. A tarefa usual é procurar o nome do arquivo de origem e entender qual destino inclui esse arquivo e sob quais condições.
Vamos encontrar menções ao arquivo “arena.cc”:
# grep arena.cc BUILD.gn
"base/arena.cc",
Ok, agora sabemos que nosso arquivo está aqui, mas não sabemos o destino. Vamos pedir algum contexto:
# grep -C2 arena.cc BUILD.gn
"base/address_tracker_linux.cc",
"base/address_tracker_linux.h",
"base/arena.cc",
"base/arena.h",
"base/backoff_entry.cc",
Não, não é tão útil. Vamos tentar ogrep
:
ogrep arena.cc BUILD.gn
102: component("net") {
385: if (!is_nacl) {
386: sources += [
409: "base/arena.cc",
Isso é útil! Sabemos imediatamente que o arquivo está incluído no destino “net” na condição “!is_nacl”.
É ainda melhor, porque ogrep
pode usar cores, aqui está uma foto:
Instale Rust e Cargo, se ainda não o fez, então
cargo install ogrep
Instale o Homebrew e então
brew install kriomant/ogrep-rs/ogrep-rs
Desculpe, ainda não, mas estou trabalhando nisso. Use Cargo por enquanto.
Existem muitas opções disponíveis, execute --help
para listá-las.
A ferramenta é útil não apenas para arquivos baseados em indentação estrita (como fonte Python) ou arquivos de construção GN, mas para uma ampla variedade de arquivos de texto, porque mesmo os que não são baseados em indentação geralmente são formatados por conveniência.
Existem até alguns hacks relacionados ao C integrados.
Aqui está uma breve lista de recursos:
O padrão é um texto fixo por padrão, mas você pode usar expressões regulares arbitrárias com -e
.
Usuais -w
(corresponder palavras inteiras) e -i
(pesquisa sem distinção entre maiúsculas e minúsculas) estão disponíveis.
A ferramenta preserva algumas linhas em branco entre as correspondências, porque ajuda a separar visualmente grupos de correspondências relacionadas, você pode desativá-la com --no-breaks
.
Às vezes é útil ver se havia outras linhas entre as correspondentes. Use --ellipsis
para isso.
Se você integrar otool
com ferramentas externas, as opções --print-filename
podem ser úteis, pois informam para imprimir o nome do arquivo se alguma correspondência for encontrada.
Por padrão, os ramos “if-else” são tratados especialmente: os ramos if são preservados para que você conheça as condições mesmo quando a correspondência é encontrada no ramo “else”:
O contexto tradicional (exibindo N linhas iniciais e/ou finais em torno de uma correspondente) também é suportado com as opções --context/-C
, --before-context/-B
e --after-context/-A
.
# ./ogrep filename_util_icu BUILD.gn
102: component("net") {
2106: if (!is_nacl) {
2210: if (use_platform_icu_alternatives) {
2222: } else {
2228: sources += [
2229: "base/filename_util_icu.cc",
Isso pode ser desligado com --no-smart-branches
.
--no-ignore-preprocessor
seja fornecido.Está planejado um tratamento mais inteligente de instruções do pré-processador (contexto paralelo).
otool
destina-se a pesquisar apenas em um único arquivo. E não é tão rápido para ser usado para pesquisar muitos arquivos. Mas você pode integrá-lo com outras ferramentas de pesquisa como esta:
grep -l cache_used -r . --include='*.cc' | xargs -n1 ogrep --print-filename cache_used
git grep
ogrep
possui integração integrada com git grep
: quando a opção -g
é fornecida, o segundo argumento é passado para git grep
como especificação de caminho. Todas as opções relevantes ( -w
, -i
, etc.) também são passadas para git grep
automaticamente, --print-filename
é forçado.
ogrep -g cache_used '*.cc'