Поиск текста через grep и rg: фильтры, обход и коды возврата

Поиск по проекту — это не только совпадение строки. Нужно выбрать корректный режим регулярного выражения, понять область обхода, не потерять скрытые файлы и отличить «ничего не…

Поиск по проекту — это не только совпадение строки. Нужно выбрать корректный режим регулярного выражения, понять область обхода, не потерять скрытые файлы и отличить «ничего не найдено» от настоящей ошибки чтения.

Точное слово, строка и регулярное выражение

grep -F ищет буквальный текст, -E включает extended regular expressions, -w ограничивает совпадение словом, а -n показывает номер строки. Для программного кода буквальный поиск часто безопаснее случайно активных метасимволов.

mkdir -p /tmp/search-demo/src
printf '%s\n' 'TODO: validate' 'method(todo)' >/tmp/search-demo/src/app.txt
grep -nF 'TODO:' /tmp/search-demo/src/app.txt
grep -nE 'TODO|FIXME' /tmp/search-demo/src/app.txt

Кавычки вокруг pattern защищают его от shell. Регистр можно игнорировать через -i, но это расширяет множество совпадений и не всегда подходит именам API.

Рекурсивный поиск в репозитории

grep -R обходит каталоги напрямую. rg по умолчанию учитывает .gitignore, пропускает скрытые и бинарные файлы и обычно удобнее для исходников.

cd /tmp/search-demo
rg --line-number --fixed-strings 'TODO:' .
rg --files --hidden --glob '!/.git/**'

Если ожидаемый файл игнорируется, используйте rg --debug для объяснения фильтра, а не сразу --no-ignore на огромном дереве. Типы и glob позволяют сузить работу: rg -t ts pattern или rg -g '*.service' pattern.

Коды завершения как часть контракта

У grep и rg status 0 означает найденное совпадение, 1 — корректный поиск без совпадений, 2 — ошибку. Поэтому set -e может остановить скрипт на нормальном результате «не найдено».

if rg -q --fixed-strings 'forbidden-token' /tmp/search-demo; then
  printf 'token found\n' >&2
  exit 1
else
  status=$?
  test "$status" -eq 1 || exit "$status"
fi

Так скрипт разрешает отсутствие строки, но не скрывает отказ в доступе или неверный pattern.

Ошибка и диагностика

Симптом «rg видит меньше файлов, чем grep -R» обычно связан с ignore-правилами, hidden или binary detection. Сначала найдите конкретный отсутствующий путь через rg --files --debug, затем проверьте ближайшие .gitignore, .ignore и глобальные правила. Не отключайте все фильтры, пока не поняли причину.

Практика

Создайте обычный, скрытый и игнорируемый файл с одним маркером. Сравните grep -R, обычный rg и rg --hidden --no-ignore. Затем напишите проверку, которая запрещает маркер, но правильно различает status 1 и 2.

Что важно запомнить

Источники