#!/bin/bash # Название выходного файла по умолчанию OUTPUT_FILE="combined_files.txt" # Директория по умолчанию INPUT_DIR="." # Флаги VERBOSE=0 RECURSIVE=1 # Массив для исключений EXCLUDE_PATHS=() # Функция для показа помощи show_help() { echo "Использование: $0 [OPTIONS]" echo "" echo "Опции:" echo " -o, --output FILE Выходной файл (по умолчанию: combined_files.txt)" echo " -i, --input DIR Входная директория (по умолчанию: текущая)" echo " -e, --exclude PATH Исключить путь (можно указать несколько раз)" echo " -r, --recursive Рекурсивный поиск (включено по умолчанию)" echo " -n, --no-recursive Не рекурсивный поиск" echo " -v, --verbose Подробный вывод" echo " -h, --help Показать эту справку" echo "" echo "Примеры:" echo " $0 -v -o result.txt" echo " $0 -i ~/projects -o /tmp/combined.txt" echo " $0 -e venv -e foto -e node_modules" echo " $0 --no-recursive --verbose -e temp" } # Парсинг аргументов командной строки while [[ $# -gt 0 ]]; do case $1 in -o|--output) OUTPUT_FILE="$2" shift 2 ;; -i|--input) INPUT_DIR="$2" shift 2 ;; -e|--exclude) EXCLUDE_PATHS+=("$2") shift 2 ;; -r|--recursive) RECURSIVE=1 shift ;; -n|--no-recursive) RECURSIVE=0 shift ;; -v|--verbose) VERBOSE=1 shift ;; -h|--help) show_help exit 0 ;; *) echo "Ошибка: Неизвестный параметр $1" echo "Используйте $0 --help для справки" exit 1 ;; esac done # Проверка существования входной директории if [[ ! -d "$INPUT_DIR" ]]; then echo "Ошибка: Директория '$INPUT_DIR' не существует" exit 1 fi # Проверка на запись в выходной файл if touch "$OUTPUT_FILE" 2>/dev/null; then rm -f "$OUTPUT_FILE" else echo "Ошибка: Нет прав для записи в '$OUTPUT_FILE'" exit 1 fi # Запоминаем текущую директорию для возврата CURRENT_DIR="$(pwd)" # Переход в входную директорию если она указана не как текущая if [[ "$INPUT_DIR" != "." ]]; then cd "$INPUT_DIR" || { echo "Ошибка: Не удалось перейти в директорию '$INPUT_DIR'" exit 1 } fi # Очищаем выходной файл > "$OUTPUT_FILE" # Счетчики total_files=0 processed_files=0 skipped_files=0 # Вывод информации о запуске if [[ $VERBOSE -eq 1 ]]; then echo "Запуск combine.sh с параметрами:" echo " Входная директория: $(pwd)" echo " Выходной файл: $OUTPUT_FILE" echo " Рекурсивный поиск: $([[ $RECURSIVE -eq 1 ]] && echo 'Да' || echo 'Нет')" if [[ ${#EXCLUDE_PATHS[@]} -gt 0 ]]; then echo " Исключения: ${EXCLUDE_PATHS[*]}" fi echo "" fi # Функция для обработки файлов process_files() { local find_cmd="find . -type f" # Если не рекурсивно, ищем только в текущей директории if [[ $RECURSIVE -eq 0 ]]; then find_cmd="find . -maxdepth 1 -type f" fi # Добавляем стандартные исключения find_cmd="$find_cmd \ -not -path \"./venv/*\" \ -not -path \"*/venv/*\" \ -not -path \"*/__pycache__/*\" \ -not -path \"*cache*\" \ -not -path \"*.pyc\" \ -not -path \"db.*\" \ -not -path \"*.lock\" \ -not -path \"*.git/*\" \ -not -path \"*.db\" \ -not -path \"*.pack\" \ -not -path \"*/node_modules/*\" \ -not -path \"./$OUTPUT_FILE\"" # Добавляем пользовательские исключения for exclude in "${EXCLUDE_PATHS[@]}"; do # Убираем начальные ./ если есть exclude="${exclude#./}" find_cmd="$find_cmd -not -path \"./$exclude\" -not -path \"./$exclude/*\" -not -path \"*/$exclude/*\"" done find_cmd="$find_cmd 2>/dev/null" # Временный файл для результатов find local temp_file=$(mktemp) # Выполняем поиск и сохраняем во временный файл eval "$find_cmd" > "$temp_file" # Обрабатываем файлы while IFS= read -r file; do [[ -z "$file" ]] && continue ((total_files++)) # Пропускаем бинарные файлы if file "$file" | grep -q "text"; then # Получаем относительный путь файла relative_path="${file#./}" if [[ $VERBOSE -eq 1 ]]; then echo "Добавляем: $relative_path" fi # Добавляем разделитель с именем файла в выходной файл { echo "# =========================================" echo "# Файл: $relative_path" echo "# =========================================" echo "" cat "$file" 2>/dev/null echo "" echo "" } >> "$OUTPUT_FILE" ((processed_files++)) else if [[ $VERBOSE -eq 1 ]]; then echo "Пропускаем (бинарный): ${file#./}" fi ((skipped_files++)) fi done < "$temp_file" # Удаляем временный файл rm -f "$temp_file" } # Запускаем обработку process_files # Возвращаемся в исходную директорию если нужно if [[ "$INPUT_DIR" != "." ]]; then cd "$CURRENT_DIR" || exit 1 fi # Итоговый отчет echo "Готово!" echo "Обработано файлов: $processed_files из $total_files" if [[ $skipped_files -gt 0 ]]; then echo "Пропущено бинарных файлов: $skipped_files" fi if [[ ${#EXCLUDE_PATHS[@]} -gt 0 ]]; then echo "Исключено путей: ${#EXCLUDE_PATHS[@]}" fi echo "Результат в: $OUTPUT_FILE" if [[ "$INPUT_DIR" != "." ]]; then echo "Исходная директория: $INPUT_DIR" fi