ripgrep, fd, bat: modern замены grep/find/cat
Классические Unix-tools (grep, find, cat, du) написаны в 1970-х. Они работают везде, но: grep не рекурсивен по умолчанию, find имеет нечитаемый синтаксис (find . -name '*.py' -exec grep -l TODO {} \;), cat не показывает синтаксис, du выводит мегабайты текста.
Modern Rust/Go replacements решают это: ripgrep (rg) — grep на стероидах с уважением .gitignore, fd — find с интуитивным синтаксисом и параллелизмом, bat — cat с подсветкой синтаксиса и line numbers, dust — du с визуальной иерархией.
В DE workflow эти tools экономят минуты на каждой задаче «поиск в коде / по логам / по конфигам». На большом monorepo разница grep -r (минуты) vs rg (секунды) меняет рабочий процесс.
В этом уроке: rg, fd, bat, dust — установка, основной синтаксис, DE use cases.
ripgrep (rg): grep на стероидах
grep -r работает, но: проходит по всем файлам включая .git, node_modules, build, требует явных include/exclude. ripgrep решает это автоматически.
Установка
# Debian/Ubuntu:
sudo apt install ripgrep
# macOS:
brew install ripgrep
# Команда называется rg:
rg --version
Дефолтное поведение
# rg рекурсивен по умолчанию:
rg ERROR
# Эквивалент grep:
grep -r ERROR .
# Но rg также:
# 1. Не лезет в .git/, node_modules/, target/, build/ (.gitignore)
# 2. Использует ВСЕ ядра CPU (parallel walking)
# 3. JIT regex engine — в разы быстрее
# 4. Подсвечивает matches в TTY
Основные опции
# Поиск:
rg PATTERN
rg PATTERN /path/to/dir
rg PATTERN file.txt # explicit file
# Тип файлов:
rg -t py "import pandas" # только Python
rg -t yaml "image:" # только YAML
rg -T js "broken" # ИСКЛЮЧИТЬ JS
# Регистр:
rg -i ERROR # case-insensitive
# Word match:
rg -w ERROR # whole word (не ERRORS, не TRACEERROR)
# Fixed string (не regex):
rg -F "1.2.3" # точка как точка, не "любой символ"
# Context (как grep -A -B -C):
rg -C 3 ERROR # 3 строки до и после
rg -A 5 ERROR # 5 строк после
# Inverted:
rg -v INFO # строки БЕЗ "INFO"
# Только имена файлов:
rg -l ERROR # files-with-matches
rg --files-without-match TEST # files без матча
# Count:
rg -c ERROR # count matches per file
Регулярные выражения (Rust regex syntax)
rg 'log_\w+\(' # log_anything(
rg '^class\s+\w+' # лидирующее class
rg 'TODO|FIXME|XXX' # альтернация
rg '\d{4}-\d{2}-\d{2}' # YYYY-MM-DD
# Не-greedy:
rg '<.*?>' # минимальный match
# PCRE2 features (-P):
rg -P '(?<=user_)\w+' # lookbehind
ripgrep по умолчанию использует Rust regex engine — быстрый, но без lookbehind/lookahead. -P переключает на PCRE2 (как у Perl) — медленнее, но мощнее.
JSON output (—json)
rg --json ERROR /var/log/app.log
# Каждый match — JSON event со строкой, началом, концом match
Полезно для интеграции в Python/Node-скрипты — структурированный output легко парсится.
.rgignore
.gitignore — паттерны игнорирования файлов в GitКак .gitignore, но для ripgrep specifically:
# .rgignore (в корне проекта):
*.log
generated/
private_data/
Полезно когда .gitignore слишком общий или нужны временные exclusions.
DE use case: поиск в логах
# Найти все ERROR за последний час в Airflow logs:
rg ERROR /var/log/airflow/ --max-count=100
# С контекстом (5 строк до):
rg -B 5 'Task failed' /var/log/airflow/dag_*.log
# Только error timestamps:
rg -o '^\S+ ERROR' /var/log/app.log | sort -u | wc -l
# Поиск конкретного query_id в DAG logs:
rg "query_id=abc-123" /var/log/airflow/
# По всем логам с конкретным DAG:
rg "DAG_ID=user_etl" /var/log/airflow/ -l # только имена файлов
DE use case: поиск в Python codebase
# Найти все usage функции:
rg -tpy "from etl.utils import process_csv"
rg -tpy "process_csv\("
# Найти все sql queries:
rg -tpy "SELECT" --multiline
rg -tpy '"""[\s\S]*?SELECT[\s\S]*?"""' --multiline
# Найти все TODO:
rg -tpy 'TODO|FIXME' --no-heading | sort -k3 -t:
# Найти все hardcoded secrets (start с типичного pattern):
rg -tpy 'password\s*=\s*"' --json | jq 'select(.type=="match")'
fd: find rewrite
find синтаксис ужасен:
# find — найти все .py файлы, изменённые за день:
find . -type f -name '*.py' -mtime -1
# fd — то же самое:
fd -e py --changed-within 1d
Установка
# Debian (пакет называется fd-find на старых системах):
sudo apt install fd-find # команда fdfind, можно alias fd=fdfind
sudo apt install fd # на новых
# macOS:
brew install fd
Основные опции
# Поиск по pattern (regex по умолчанию):
fd 'config' # все файлы/директории с 'config' в имени
fd '\.py$' # точный regex
# Glob mode:
fd -g '*.py' # как find -name
# Тип:
fd -t f config # только files
fd -t d config # только directories
fd -t l # symbolic links
fd -t x # executables
# Extension:
fd -e py # .py files
fd -e py -e pyi # .py или .pyi
# Изменения по времени:
fd --changed-within 1d
fd --changed-before 1w
# Включить hidden:
fd -H config # включая .config директории
# Включить gitignored:
fd -I # ignore .gitignore
# Execute:
fd -e py -x wc -l # подсчитать строки в каждом .py
fd -e tmp -X rm # удалить все .tmp файлы (-X = одна команда со всеми)
Реальные DE use cases
# Найти все CSV больше 100MB:
fd -e csv -S +100M
# Удалить все .pyc файлы:
fd -e pyc -X rm
# Найти DAGs, изменённые за сутки:
fd -e py --changed-within 1d /opt/airflow/dags
# Конвертировать все .json в .jsonl через jq:
fd -e json -x sh -c 'jq -c ".[]" "{}" > "{.}.jsonl"'
bat: cat с подсветкой
cat показывает файл как plain text. bat — то же самое + syntax highlighting + line numbers + git diff indicators.
# Установка:
sudo apt install bat # Debian/Ubuntu (команда batcat) или bat (новых)
brew install bat # macOS
# Использование как cat:
bat config.yaml
bat /var/log/syslog
bat -p file.py # plain mode (без line numbers/header)
# Несколько файлов:
bat *.py
# С line range:
bat -r 10:50 large_file.py # строки 10-50
bat для fzf preview
# В ~/.bashrc:
export FZF_DEFAULT_OPTS="--preview 'bat --color=always --style=numbers --line-range=:200 {}'"
Теперь каждый fzf preview подсвечен и красив.
bat как pager для man
export MANPAGER="sh -c 'col -bx | bat -l man -p'"
man find # теперь подсвеченный man-page
dust: du с визуализацией
du -sh */ — текстовый вывод сортированный alphabetically. Найти “что занимает место” — pain.
dust показывает tree с прогресс-барами:
sudo apt install du-dust # пакет называется du-dust
brew install dust
# Использование:
dust /var/log
# Output:
# 12G /var/log
# ├─ 5G apt
# ├─ 4G journal
# │ ├─ 3G user-1000
# │ └─ 1G system
# ├─ 2G airflow
# └─ 1G syslog.1
Цветной tree с относительными размерами как ASCII-bar. Идеально для disk-space-investigation на production.
# Глубина:
dust -d 3 /var/log
# Сортировка:
dust -r # reverse (smallest first)
# Только файлы:
dust -F /var/log
Дополнительные modern tools
entr — re-run on file change
sudo apt install entr
brew install entr
# Запустить тесты при изменении любого .py:
ls *.py | entr -r pytest
# Restart Python скрипт при изменении:
echo myscript.py | entr -r python myscript.py
# Lint скрипт при изменении:
ls *.sh | entr shellcheck /_
Hot-reload без специальных tools — для bash/SQL/manual scripts.
duf — df с UI
sudo apt install duf
brew install duf
duf
# Красивая таблица filesystems с usage bars, типами, mount points
procs — ps replacement
brew install procs
procs # цветная таблица процессов с tree view
procs node # filter
sd — sed replacement
brew install sd
# sed:
sed -E 's/(\w+)@(\w+)\.com/\1 at \2/' file.txt
# sd:
sd '(\w+)@(\w+)\.com' '$1 at $2' file.txt
Более интуитивный синтаксис, поддерживает modern regex flavor.
Установка всех сразу
# Debian/Ubuntu:
sudo apt install ripgrep fd-find bat du-dust entr duf
# macOS:
brew install ripgrep fd bat dust entr duf procs sd
# Или одной командой через homebrew bundle:
cat > Brewfile <<EOF
brew "ripgrep"
brew "fd"
brew "bat"
brew "dust"
brew "entr"
brew "duf"
brew "procs"
brew "sd"
EOF
brew bundle
Когда использовать modern vs классику
В скриптах, которые деплоятся на production servers, не полагайся на rg/fd. Используй классический grep/find. Modern tools — для локальной продуктивности (поиск по логам через SSH с rg тоже работает, если ставить его на сервер). Знай оба, используй по контексту.
Cross-links
- Урок 02 (fzf) — fzf использует find по умолчанию; переключи на fd через
FZF_DEFAULT_COMMAND. bat для--preview. - Урок 04 (tmux) — modern tools полезны в panes.
- Урок 05 (shell power) — zoxide, direnv, starship.
- Модули 06-07 (text processing) — классические grep/sed/awk, основы.
Попробуй сам
- Установи rg, fd, bat:
# Linux:
sudo apt install ripgrep fd-find bat
# macOS:
brew install ripgrep fd bat
- Сравни скорости в проекте:
cd /your/large/project
time grep -r 'function' . > /dev/null
time rg 'function' > /dev/null
- Найди все Python с TODO:
rg -tpy 'TODO|FIXME' --no-heading | head -20
- Найди файлы изменённые за день:
fd --changed-within 1d -t f .
- Открой config с bat:
bat /etc/ssh/sshd_config
- Disk-space investigation:
dust ~
- Auto-run tests on save:
ls *.py | entr -r pytest
# Жми Ctrl-C для остановки