This commit is contained in:
2026-02-01 19:09:26 +03:00
parent 0b01f30021
commit e238813980
3 changed files with 157 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
#!/usr/bin/env python3
"""
Скрипт объединения нескольких JSON-файлов в один.
Файлы должны лежать в том же каталоге, что и скрипт. Каждый файл — один JSON-объект;
результат — один объект, собранный из верхнеуровневых ключей всех файлов.
При совпадении ключей побеждает значение из файла, идущего позже в списке.
"""
import argparse
import json
from pathlib import Path
def get_script_dir() -> Path:
"""Возвращает каталог, в котором расположен скрипт."""
return Path(__file__).resolve().parent
def merge_json_files(
filenames: list[str],
base_dir: Path,
output_path: Path,
indent: int | None = 2,
) -> None:
"""
Читает перечисленные JSON-файлы из base_dir и записывает объединённый объект в output_path.
Args:
filenames: Список имён файлов (без пути).
base_dir: Каталог с входными файлами.
output_path: Полный путь к результирующему JSON-файлу.
indent: Отступ для форматирования JSON (по умолчанию 2).
Raises:
FileNotFoundError: Если какой-либо входной файл не найден.
json.JSONDecodeError: Если содержимое файла не является валидным JSON.
"""
result: dict = {}
for name in filenames:
path = base_dir / name
if not path.is_file():
raise FileNotFoundError(f"Файл не найден: {path}")
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
if not isinstance(data, dict):
raise TypeError(
f"Файл {name} должен содержать JSON-объект (dict), получен: {type(data).__name__}"
)
result.update(data)
with open(output_path, "w", encoding="utf-8") as f:
json.dump(result, f, ensure_ascii=False, indent=indent)
def main() -> None:
"""Точка входа: разбор аргументов и вызов объединения."""
script_dir = get_script_dir()
parser = argparse.ArgumentParser(
description="Объединить несколько JSON-файлов из каталога скрипта в один файл."
)
parser.add_argument(
"files",
nargs="+",
metavar="FILE",
help="Имена JSON-файлов (в каталоге скрипта)",
)
parser.add_argument(
"-o",
"--output",
default="merged.json",
metavar="OUTPUT",
help="Имя результирующего файла (по умолчанию: merged.json)",
)
parser.add_argument(
"--no-indent",
action="store_true",
help="Не форматировать вывод (компактный JSON)",
)
args = parser.parse_args()
output_path = script_dir / args.output
indent = None if args.no_indent else 2
merge_json_files(
filenames=args.files,
base_dir=script_dir,
output_path=output_path,
indent=indent,
)
print(f"Записано: {output_path}")
if __name__ == "__main__":
main()