open atlas
↑ К треку
Командная строка CLI · 04 · 03

Поиск содержимого командой grep

grep ищет содержимое файлов по шаблону. -r обходит всё дерево каталогов; -n показывает номера строк; -i игнорирует регистр; -l выводит только имена совпавших файлов; --include ограничивает поиск конкретными типами файлов.

CLI Junior ◷ 20 min
Уровень
ОсновыJuniorMiddleSenior

find находит файлы по метаданным — имени, размеру, возрасту. Но что если нужно найти файлы по тому, что внутри них? Какой исходный файл вызывает getUserById? Какой конфиг устанавливает MAX_CONNECTIONS? Это работа grep: он читает содержимое файлов строка за строкой и выводит каждую строку, совпадающую с шаблоном.

К концу урока ты будешь искать текстовые шаблоны в целых деревьях каталогов, управлять форматом вывода и использовать базовые регулярные выражения с grep.

Цель

После этого урока ты сможешь запускать grep -r для поиска шаблона в дереве каталогов, добавлять -n для номеров строк, -i для поиска без учёта регистра, -l для вывода только имён совпавших файлов и --include для ограничения поиска конкретными расширениями файлов. Ты также сможешь писать простые регулярные выражения для grep.

1

Базовый grep: шаблон затем файл(ы). grep выводит каждую строку в файле(ах), содержащую шаблон:

grep "error" app.log           # строки с "error" в app.log
grep "TODO" src/main.ts        # строки с TODO в одном файле
grep "timeout" *.conf          # поиск по всем .conf файлам в текущем каталоге

Шаблон по умолчанию — Базовое Регулярное Выражение (BRE). Для Расширенных Регулярных Выражений (ERE) добавь -E; для Perl-совместимых — -P.

2

-r выполняет рекурсивный поиск в дереве каталогов. Это флаг, который ты будешь использовать чаще всего в ежедневной работе:

grep -r "getUserById" src/       # поиск по каждому файлу под src/
grep -r "MAX_CONNECTIONS" /etc/  # поиск по всем конфигам под /etc

Формат вывода: имя_файла:содержимое_строки. grep следует символическим ссылкам с -r только при использовании -R (заглавная) в GNU grep; -r по умолчанию не следует ссылкам.

3

-n, -i, -l управляют форматом вывода.

  • -n — добавляет номер строки перед каждой совпадающей строкой:
grep -rn "panic" ./logs/     # grep -r -n вместе; показывает файл:номерстроки:строка
  • -i — поиск без учёта регистра. Находит Error, error, ERROR:
grep -ri "error" src/
  • -l — выводит только имена файлов, содержащих совпадение (подавляет сами строки). Полезно, когда нужно знать только, какие файлы затронуты:
grep -rl "deprecated" src/     # какие файлы упоминают "deprecated"?

Флаги свободно комбинируются: grep -rnil "TODO" . — совершенно допустимо.

4

--include и --exclude сужают набор файлов. Без них -r ищет по каждому файлу, включая бинарные. Глоб --include сопоставляется с именем файла:

grep -r "import" src/ --include="*.ts"      # только TypeScript файлы
grep -r "password" . --include="*.{yml,yaml,json}"  # только конфиги
grep -r "debug" . --exclude="*.min.js"      # пропустить минифицированный JS

Глоб в --include обрабатывается grep, а не оболочкой — бери его в кавычки для надёжности.

5

Базовые регулярные выражения в grep. Шаблоны grep — не просто строки, по умолчанию это BRE:

МетасимволЗначениеПример
.любой одиночный символgr.p находит grep, grap, gr9p
*ноль или более предыдущегоerr.*or находит error, err0r, errXXXXor
^начало строки^import находит строки, начинающиеся с import
$конец строки};$ находит строки, заканчивающиеся на };
[...]класс символов[Ee]rror находит Error или error
\bграница слова (GNU)\berror\b находит error, но не errors

Используй -F (фиксированная строка), когда не нужна интерпретация регулярных выражений — самый быстрый вариант для поиска обычного текста.

grep -rn "^import " src/ --include="*.ts"    # строки, начинающиеся с "import "
grep -rF "process.exit(1)" .                 # буквальная строка, без regex
Разбор примера

Поиск всех использований устаревшей функции в TypeScript-проекте.

Нужно найти каждый вызов legacyFetch, чтобы заменить его:

grep -rn "legacyFetch" src/ --include="*.ts"

Пример вывода:

src/api/users.ts:14:  const data = await legacyFetch('/users');
src/api/posts.ts:8:   return legacyFetch('/posts/' + id);
src/utils/http.ts:3:  export function legacyFetch(url: string) {

Три файла с номерами строк. Теперь выведем только имена файлов для планирования рефакторинга:

grep -rl "legacyFetch" src/ --include="*.ts"
src/api/users.ts
src/api/posts.ts
src/utils/http.ts

Передадим в wc -l, чтобы подсчитать количество затронутых файлов:

grep -rl "legacyFetch" src/ --include="*.ts" | wc -l
3
Почему это работает

BSD grep (macOS) против GNU grep (Linux). Они разделяют основные флаги (-r, -n, -i, -l), но отличаются в деталях:

  • --include и --exclude работают на обеих платформах, но --include-dir — только GNU.
  • -P (Perl-совместимые regex) — только GNU; BSD grep его не поддерживает. Используй -E (ERE) для переносимых расширенных шаблонов.
  • Цветной вывод (--color=auto) работает на обеих, но умолчание отличается.

Для скриптов, которые должны работать на macOS, используй только BRE/ERE (-E) и избегай -P. Или установи GNU grep через Homebrew (brew install grep) и вызывай его как ggrep.

Частая ошибка

Использование grep -r по большому дереву без --include захватывает бинарные файлы и работает медленно. grep попытается прочитать каждый файл — скомпилированные бинарники, изображения, объекты .git. Добавь --include для ограничения текстовыми расширениями и --exclude-dir=.git для пропуска объектов системы контроля версий:

# Медленно и шумно: бинарные совпадения выводятся как "Binary file X matches"
grep -r "config" .

# Быстро и чисто
grep -r "config" . --include="*.{ts,js,json,yml}" --exclude-dir=.git
Проверь себя
Викторина

Нужно найти, какие файлы под src/ содержат слово 'TODO', ища только в .ts-файлах, без вывода совпавших строк — только имена файлов. Какая команда верна?

Итог

grep шаблон файл(ы) выводит каждую строку, совпадающую с шаблоном. -r расширяет поиск рекурсивно по дереву каталогов; -n добавляет номера строк; -i делает сопоставление нечувствительным к регистру; -l выводит только имена файлов. --include="*.ext" сужает поиск до конкретных типов файлов — всегда используй с -r, чтобы избежать сканирования бинарников и .git. Шаблоны grep по умолчанию — Базовые Регулярные Выражения; добавь -E для расширенного синтаксиса или -F для поиска буквальной строки без regex.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 4 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.