6
август
2025
Пакетные операции с файлами - переименование и объединение PDF
18:24

Пакетные операции с файлами - переименование и объединение PDF

6 август 2025 18:24

Решил поделиться двумя программами на языке Python. Первая - переименование файлов по порядковому номеру в зависимости от даты создания. Вторая - объединение PDF файлов по их номеру.

Задача на работе была в том, что сканировали последние листы руководства пользователя, где указан серийный номер. Таких получалось 6 файлов.

Комплекты документов раскладывались вручную по папкам, с номерами 01, 02, 03, и т.д. до последнего.
Один лист - один файл PDF. Затем часть из них объединялись по два листа.

Папка 01 содержит 6 файлов

  • случайное имя. PDF
  • случайное имя. PDF
  • случайное имя. PDF
  • случайное имя. PDF
  • случайное имя. PDF
  • случайное имя. PDF

Задача: получить в папке 01 комплект
01_res1.pdf
01_res2.pdf
01_res3.pdf
01_res4.pdf

Разделил задачу на две подзадачи:

  • обход папок и переименование файлов по дате создания - в имя папки + порядковый номер: 01-1.pdf, 01-2.pdf, 01-3.pdf, 01-4.pdf, 01-5.pdf и 01-6.pdf.
  • объединение файлов по алгоритму: 3 и 4 в один файл PDF, 5 и 6 в другой файл PDF.

Первый скрипт rename_files.py может пригодится для пакетного переименования файлов не только формата PDF, а любых.
Второй скрипт combine_files.py реализует логику объединения файлов PDF в каждом из каталогов.


Входной параметр для запуска программ - имя родительской папки (которая содержит вложенные папки 01, 02, 03 и т.д.).

Пример запуска:

python rename_files.py /home/user/parent_folder
python combine_files.py /home/user/parent_folder

где parent_folder содержит папки 01, 02, 03 и т.д. с файлами PDF.

Запускать rename_files.py с осторожностью, не на рабочем каталоге, т.к. переименование всех файлов происходит в пакетном режиме без запроса.

Содержимое файла rename_files.py:

# This script takes path to directory with set of subdirectories, numbered 01, 02, 03, ... etc.

and renames PDF files in subdirectories after the name of subdirectory and integer number in order of creation of the file.

example: before script run subdirectory 01 consists of files : random912371.pdf, random167722.pdf, random561724.pdf

and after the script run, in subdirectory 01 files renamed to: 01-1.pdf,

01-2.pdf, 01-3.pdf

import os
from pathlib import Path
import sys
import pathlib

def list_dirs(folder_path):
for filename in os.listdir(folder_path):
file_path = os.path.join(folder_path, filename)
if os.path.isdir(file_path):
dir_path = file_path
print(f"Processing directory '{dir_path}'")
rename_files_with_creation_date(dir_path)
print("Done!")

def rename_files_with_creation_date(folder_path):

tpl = "{0}-{num:02d}"

tpl = "{0}-{num}"
cnt = 1
folder_name = folder_path.split("/")[-1]
parent_folder_name = os.path.split(folder_path)[-1]
os.chdir(folder_path)
files = filter(os.path.isfile, os.listdir(folder_path))  # get files only
files = [os.path.join(folder_path, f)
         for f in files]  # add path folder_path to each file f
files.sort(key=lambda x: os.path.getmtime(x))  # sort by creation time

for filename in files:
    # print(f"{cnt}. Renaming '{filename}'...")
    if os.path.isfile(filename):
        ext = pathlib.Path(filename).suffix
        new_name = tpl.format(folder_name, num=cnt) + ext
        filename_new = os.path.join(folder_path, new_name)
        if (filename != filename_new):
            print(f"Ranaming '{filename}' to '{filename_new}'")
            if not os.path.isfile(filename_new):
                os.rename(filename, filename_new)
                # print("OK")
            else:
                print(f"File '{filename_new}' exists, skipping.")
        cnt = cnt + 1

if name == "main":
if len(sys.argv) == 2:
folder_path = sys.argv[1]
else:
folder_path = input("Enter the folder path: ")
list_dirs(folder_path)

Кроме объединения, в файле combine_files.py реализован поворот страниц из портретного в альбомный вид (на 90 градусов). Эту трансформацию можно убрать путём редактирования исходного текста скрипта.

# This script combines files

import os
import sys
import pathlib
import logging
import threading
import time
from pathlib import Path
from subprocess import PIPE, run

def list_dirs(folder_path):
for filename in os.listdir(folder_path):
file_path = os.path.join(folder_path, filename)
if os.path.isdir(file_path):
dir_path = file_path
print(f"Processing directory '{dir_path}'")
combine_files(dir_path)
print("Done!")

def combine_files(folder_path):
folder_name = folder_path.split("/")[-1]
parent_folder_name = os.path.split(folder_path)[-1]
os.chdir(folder_path)
files = filter(os.path.isfile, os.listdir(folder_path))
files = sorted(files)

cnt = 1
for filename in files:
    full_name = os.path.join(folder_path, filename)
    if (filename == parent_folder_name + "-1.pdf"):
        suffix = "_res1.pdf"
        new_name = folder_name + suffix
        cmdstr = "qpdf " + full_name + " " + new_name + " --rotate=+90"
        print(cmdstr)
        result = run(cmdstr.split(" "))
        time.sleep(1)
        cmdstr = "rm " + full_name
        print(cmdstr)
        result = run(cmdstr.split(" "))
    if (filename == parent_folder_name + "-2.pdf"):
        suffix = "_res2.pdf"
        new_name = folder_name + suffix
        new_name = os.path.join(folder_path, new_name)
        cmdstr = "qpdf " + full_name + " " + new_name + " --rotate=+90"
        print(cmdstr)
        result = run(cmdstr.split(" "))
        time.sleep(1)
        cmdstr = "rm " + full_name
        print(cmdstr)
        result = run(cmdstr.split(" "))
    if (filename == parent_folder_name + "-3.pdf"):
        suffix = "_res3.pdf"
        new_name = folder_name + suffix
        full_new_name = os.path.join(folder_path, new_name)
        cmdstr = "qpdf --empty --pages " + full_name + " " + \
            full_name.replace("3.pdf", "4.pdf") + " -- --rotate=+90 " + full_new_name
        print(cmdstr)
        result = run(cmdstr.split(" "))
        time.sleep(1)
        cmdstr = "rm " + full_name
        print(cmdstr)
        result = run(cmdstr.split(" "))
    if (filename == parent_folder_name + "-4.pdf"):
        cmdstr = "rm " + os.path.join(folder_path, filename)
        print(cmdstr)
        result = run(cmdstr.split(" "))
    if (filename == parent_folder_name + "-5.pdf"):
        suffix = "_res4.pdf"
        new_name = folder_name + suffix
        full_new_name = os.path.join(folder_path, new_name)
        cmdstr = "qpdf --empty --pages " + full_name + " " + \
            full_name.replace("5.pdf", "6.pdf") + " -- --rotate=+90 " + full_new_name
        print(cmdstr)
        result = run(cmdstr.split(" "))
        time.sleep(1)
        cmdstr = "rm " + os.path.join(folder_path, filename)
        print(cmdstr)
        result = run(cmdstr.split(" "))
    if (filename == parent_folder_name + "-6.pdf"):
        cmdstr = "rm " + os.path.join(folder_path, filename)
        print(cmdstr)
        result = run(cmdstr.split(" "))

if name == "main":
if len(sys.argv) == 2:
folder_path = sys.argv[1]
else:
folder_path = input("Enter the folder path: ")
list_dirs(folder_path)

Архив с 2 программами:
rename_files_by_created_date_and_combine.zip

Идею переименования файлов взял отсюда: GitHub - rename files by created date, но там имя файла в виде День_Месяц_Год_Час_Минута_секунда, а у меня ИМЯ_ПАПКИ-порядковый_номер.



Похожие публикации