Поиск текста через 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.
Что важно запомнить
- Выбирайте
-Fдля буквального текста и-Eтолько когда нужен regex. - Область поиска важна не меньше pattern; у rg есть осознанные ignore-правила.
- «Нет совпадений» и «поиск сломан» имеют разные коды и требуют разных действий.