Кладовочка

О разном, чтобы было под рукой онлайн

Linux-инструменты для анализа кода и текста: от grep до ast-grep

Эти инструменты превращают терминал в полноценную среду анализа кода — без IDE, без плагинов, без LLM. От поиска паттернов до подсчёта сложности и поиска дубликатов.

Базовые: grep, awk, sed

grep — поиск по содержимому

# Рекурсивный поиск TODO/FIXME
grep -rn "TODO\|FIXME" --include="*.py" .

# Поиск функций с подсчётом
grep -c "def " *.py

# Поиск с контекстом (2 строки до и после)
grep -C 2 "import pandas" *.py

# Поиск с подсветкой и номерами строк
grep -rn --color=always "class.*:" --include="*.py" .

awk — обработка структурированного текста

# Статистика по длине строк кода
awk '{print length, $0}' script.py | sort -rn | head

# Подсчёт импортов по модулям
grep "^import\|^from" *.py | awk '{print $2}' | sort | uniq -c

# Анализ CSV: третья колонка, где вторая > 100
awk -F',' '$2 > 100 {print $3}' data.csv

# Подсчёт циклов и условий (приблизительная сложность)
awk '/if |for |while / {count++} END {print "Complexity:", count}' script.py

sed — потоковое редактирование

# Удаление комментариев (подготовка для LLM)
sed 's/#.*$//' script.py | sed '/^$/d'

# Замена множественных пробелов
sed 's/  */ /g' messy_code.txt

# Извлечение строк между маркерами
sed -n '/START/,/END/p' logfile.txt

Структура проекта

Инструмент Команда Что делает
tree tree -L 3 -I 'node_modules|.git' Дерево проекта с фильтрацией
tree tree -h -s --du Дерево с размерами
fd fd -e py -x wc -l {} Подсчёт строк в каждом Python-файле
fd fd -t d -d 2 Все директории на глубину 2
fd fd TODO --type f Поиск файлов с TODO
exa/eza eza -la --tree -L 2 --git Современная замена ls с деревом

fd — современная замена find. Быстрее, дружелюбный вывод, умные дефолты (игнорирует .git, node_modules).

# Установка
sudo apt install fd-find  # Ubuntu
# или
cargo install fd-find

Поиск по содержимому: ripgrep

ripgrep (rg) — современная замена grep. В 5–10 раз быстрее на больших проектах.

# Поиск всех вызовов функции во всех файлах
rg "function_name\(" --type py

# Поиск с контекстом
rg -C 3 "TODO" --type ts

# Подсчёт вхождений по файлам
rg -c "import" --type py | sort -t: -k2 -rn

# Поиск с заменой (dry-run)
rg "old_api" --type py -l | xargs sed -i 's/old_api/new_api/g'

# Исключить файлы и директории
rg "pattern" -g '!*.min.js' -g '!dist/'

Статистика кода: tokei, cloc, scc

Эти утилиты считают строки кода, комментарии и пустые строки по языкам.

# tokei — самый быстрый (Rust), красивый вывод
tokei . --sort lines

# cloc — классика, поддерживает 300+ языков
cloc . --by-file

# scc — ещё быстрее, сложностные метрики
scc . --complexity

Сравнение на проекте из 100K строк:

Инструмент Время Языков
tokei 0.3 с Rust
scc 0.2 с Go
cloc 15 с Perl

scc также оценивает когнитивную сложность по строкам.

JSON: jq

# Извлечение поля из API-ответа
curl -s https://api.example.com/data | jq '.items[].name'

# Фильтрация
jq '.[] | select(.status == "error")' errors.json

# Группировка и подсчёт
jq 'group_by(.severity) | map({level: .[0].severity, count: length})' issues.json

# Переформатирование
jq '{total: .count, names: [.items[].name]}' data.json

# Слияние нескольких JSON-файлов
jq -s 'add' file1.json file2.json file3.json

AST-анализ: ast-grep, semgrep, comby

В отличие от grep, эти инструменты понимают синтаксическую структуру кода.

ast-grep — поиск по AST (абстрактному синтаксическому дереву)

# Найти все вызовы console.log с любым аргументом
ast-grep -p "console.log($$$)" --lang js

# Найти присваивания без тип-аннотаций
ast-grep -p "var $A = $_" --lang py

# Замена с сохранением форматирования
ast-grep -p "oldFunction($$$ARGS)" -r "newFunction($$$ARGS)" --lang ts

semgrep — поиск паттернов кода

# Поиск использования eval (потенциальная уязвимость)
semgrep -e 'eval(...)' --lang py

# Поиск хардкоженных секретов
semgrep --config "p/secrets" .

# Собственный rule для поиска опасных паттернов
semgrep -e 'pickle.loads(...)' --lang py

# Генерация SARIF-отчёта для CI
semgrep --config auto --sarif -o results.sarif .

comby — структурный поиск и замена

# Замена во всех языках
comby 'console.log(:[args])' 'logger.info(:[args])' -in-place

# Поиск с контекстом
comby ':[f](:[args])' '' -match-only -count

Сложность кода: radon, lizard, flake8, pylint

radon (Python)

# Цикломатическая сложность
radon cc . -a -s

# Индекс поддерживаемости
radon mi . -s

# Сырые метрики (LOC, комментарии)
radon raw .

lizard (мультиязычный)

# Сложность всех файлов в проекте
lizard . -l python

# Только функции со сложностью > 10
lizard . -C 10

# HTML-отчёт
lizard . --html > report.html

mypy, pyright, pyre (Type Checking)

mypy src/ --strict            # Строгая проверка типов
pyright --outputjson src/     # JSON для CI
pyre check                    # Facebook-овский статический анализ

Зависимости: madge, pipdeptree, dependency-cruiser

# madge — граф зависимостей (JS/TS)
madge --image graph.svg src/index.ts
madge --circular src/         # Поиск циклических зависимостей

# pipdeptree — дерево зависимостей Python
pipdeptree --warn silence | grep -E '^\w+'

# dependency-cruiser — ещё мощнее для JS/TS
depcruise --include-only "^src" --output-type dot src | dot -T svg > deps.svg
depcruise src --validate .dependency-cruiser.js  # CI-проверка

Дубликаты: jscpd

# Поиск дубликатов во всём проекте
jscpd . --min-tokens 50 --min-lines 5

# Только для Python
jscpd . --pattern "**/*.py" --reporters html,json

# Для CI: порог 5% дублирования
jscpd . --threshold 5

Безопасность: gitleaks, trivy, syft

# gitleaks — поиск секретов в git-истории
gitleaks detect --source . --verbose

# trivy — сканирование уязвимостей
trivy fs . --scanners vuln,secret,misconfig

# syft — SBOM (Software Bill of Materials)
syft . -o json > sbom.json

Готовые пайплайны

Быстрый аудит нового проекта

#!/bin/bash
# Полный аудит проекта за 30 секунд
PROJECT_DIR="${1:-.}"

echo "=== СТРУКТУРА ==="
tree -L 3 -I 'node_modules|.git|__pycache__|venv|build' "$PROJECT_DIR"

echo -e "\n=== СТАТИСТИКА ==="
tokei "$PROJECT_DIR" --sort lines | head -20

echo -e "\n=== ЦИКЛОМАТИЧЕСКАЯ СЛОЖНОСТЬ (топ-10) ==="
radon cc "$PROJECT_DIR" --min B -s 2>/dev/null | head -20 || \
  lizard "$PROJECT_DIR" -C 10 2>/dev/null | head -20

echo -e "\n=== ДУБЛИКАТЫ ==="
jscpd "$PROJECT_DIR" --min-tokens 50 --min-lines 5 --silent 2>/dev/null

echo -e "\n=== ПОИСК СЕКРЕТОВ ==="
gitleaks detect --source "$PROJECT_DIR" --no-git -v 2>/dev/null

echo -e "\n=== ЦИКЛИЧЕСКИЕ ЗАВИСИМОСТИ ==="
madge --circular "$PROJECT_DIR/src" 2>/dev/null

Поисково-аналитический пайплайн

#!/bin/bash
# Найти файл → проанализировать содержимое → сохранить отчёт
QUERY="${1:?Укажите поисковый запрос}"
OUTPUT="${2:-report.md}"

echo "# Анализ по запросу: $QUERY" > "$OUTPUT"
echo "**Дата:** $(date)" >> "$OUTPUT"
echo "" >> "$OUTPUT"

# 1. Поиск релевантных файлов
echo "## 1. Файлы, содержащие '$QUERY'" >> "$OUTPUT"
echo '```' >> "$OUTPUT"
rg -l "$QUERY" --type-add 'code:*.{py,js,ts,rs,go}' --type code . >> "$OUTPUT"
echo '```' >> "$OUTPUT"
echo "" >> "$OUTPUT"

# 2. Подсчёт вхождений по файлам
echo "## 2. Частота по файлам" >> "$OUTPUT"
echo '```' >> "$OUTPUT"
rg -c "$QUERY" --type-add 'code:*.{py,js,ts,rs,go}' --type code . | \
  sort -t: -k2 -rn >> "$OUTPUT"
echo '```' >> "$OUTPUT"
echo "" >> "$OUTPUT"

# 3. Контекст
echo "## 3. Контекст использования" >> "$OUTPUT"
echo '```' >> "$OUTPUT"
rg -C 1 "$QUERY" --type-add 'code:*.{py,js,ts,rs,go}' --type code . \
  2>/dev/null | head -100 >> "$OUTPUT"
echo '```' >> "$OUTPUT"

echo "Отчёт сохранён в $OUTPUT"

Шпаргалка: что и когда использовать

Задача Инструмент Команда
Поиск по содержимому ripgrep rg "pattern" --type py
Поиск по AST ast-grep ast-grep -p "pattern" --lang py
Поиск уязвимостей semgrep semgrep --config auto
Статистика кода tokei/scc tokei . --sort lines
Структура проекта tree/fd fd -t d -d 3
Цикломатическая сложность radon/lizard radon cc . -a
Дубликаты кода jscpd jscpd . --min-tokens 50
Зависимости madge/pipdeptree madge --circular src/
Секреты в коде gitleaks gitleaks detect -v
JSON-анализ jq jq '.items[] | .name'
Замена по AST comby comby 'old(:[x])' 'new(:[x])'