Files
linux_tools/combine.sh
2026-05-12 18:14:36 +03:00

216 lines
6.9 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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