Функциональный инструмент для поиска в текстовых файлах со структурой отступов.
Вдохновлен огрепом Мэтта Брубека. Этот огреп компактный и красивый, но не функциональный.
См. также ogrep — порт этого инструмента, написанный на Python (правда, он был первым).
ogrep
очень похож на grep
: оба могут искать совпадения и отображать их контекст. Но контекст в grep
— это «N строк до/после совпадения», а в ogrep
— «строки выше совпадающей с меньшим отступом».
Позвольте мне объяснить. Я использую этот инструмент в основном при работе с файлами сборки GN, поэтому в качестве примера я буду использовать какой-нибудь большой файл BUILD.gn. Обычная задача — найти имя исходного файла и понять, в какую цель входит этот файл и при каких условиях.
Найдем упоминания о файле «arena.cc»:
# grep arena.cc BUILD.gn
"base/arena.cc",
Хорошо, теперь мы знаем, что наш файл здесь, но мы не знаем цель. Давайте попросим немного контекста:
# 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",
Нет, не так уж и полезно. Давайте попробуем ogrep
:
ogrep arena.cc BUILD.gn
102: component("net") {
385: if (!is_nacl) {
386: sources += [
409: "base/arena.cc",
Вот это полезно! Мы сразу узнаем, что файл включен в цель «net» при условии «!is_nacl».
Это даже лучше, потому что ogrep
умеет использовать цвета, вот картинка:
Установите Rust and Cargo, если еще не сделали, то
cargo install ogrep
Установите Homebrew, затем
brew install kriomant/ogrep-rs/ogrep-rs
Извините, пока нет, но я работаю над этим. Используйте Cargo сейчас.
Существует множество доступных опций, запустите --help
, чтобы просмотреть их.
Инструмент полезен не только для файлов со строгими отступами (например, исходный код Python) или файлов сборки GN, но и для широкого спектра текстовых файлов, поскольку даже те, которые не основаны на отступах, обычно форматируются для удобства.
Есть даже несколько встроенных хаков, связанных с C.
Вот краткий список функций:
По умолчанию шаблон представляет собой фиксированный текст, но вы можете использовать произвольное регулярное выражение с -e
.
Доступны обычные -w
(полное совпадение слов) и -i
(поиск без учета регистра).
Инструмент сохраняет некоторые пустые строки между совпадениями, поскольку он помогает визуально разделить группы связанных совпадений. Вы можете отключить его с помощью --no-breaks
.
Иногда полезно посмотреть, были ли между совпавшими строками другие строки. Используйте для этого --ellipsis
.
Если вы интегрируете otool
с внешними инструментами, опция --print-filename
может оказаться полезной: она указывает на необходимость печати имени файла, если найдено какое-либо совпадение.
По умолчанию ветки if-else обрабатываются особым образом: ветки if сохраняются, поэтому вы знаете условия, даже если совпадение найдено в ветке else:
Традиционный контекст (отображение N начальных и/или конечных строк вокруг совпавшей строки) также поддерживается опциями --context/-C
, --before-context/-B
и --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",
Это можно отключить с помощью --no-smart-branches
.
--no-ignore-preprocessor
.Планируется более интеллектуальная обработка инструкций препроцессора (параллельный контекст).
otool
предназначен для поиска только в одном файле. И это не так быстро, чтобы его можно было использовать для поиска по большому количеству файлов. Но вы можете интегрировать его с другими инструментами поиска, например:
grep -l cache_used -r . --include='*.cc' | xargs -n1 ogrep --print-filename cache_used
git grep
ogrep
имеет встроенную интеграцию с git grep
: если указана опция -g
, второй аргумент передается в git grep
в качестве указания пути. Все соответствующие параметры ( -w
, -i
и т. д.) также автоматически передаются в git grep
, --print-filename
принудительно.
ogrep -g cache_used '*.cc'