combine.sh

This commit is contained in:
jads
2026-05-12 18:14:36 +03:00
parent 4122afeda6
commit c7edca3c3e
2 changed files with 221 additions and 1 deletions

215
combine.sh Executable file
View File

@@ -0,0 +1,215 @@
#!/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