>  기사  >  백엔드 개발  >  Python을 사용하여 두 디렉터리 간 파일 동기화

Python을 사용하여 두 디렉터리 간 파일 동기화

王林
王林원래의
2024-08-16 18:01:091046검색

Synchronizing Files Between Two Directories Using Python

디렉터리 간 파일 동기화는 백업 관리, 여러 저장 위치 간의 일관성 보장 또는 단순히 데이터 정리를 위한 일반적인 작업입니다.

이 작업을 수행하는 데 사용할 수 있는 도구는 많지만 디렉터리 동기화를 처리하는 Python 스크립트를 생성하면 유연성과 제어 기능이 제공됩니다.

이 가이드에서는 두 디렉터리 간에 파일을 동기화하도록 설계된 Python 스크립트를 안내합니다.


스크립트 소개

스크립트는 여러 필수 Python 라이브러리를 가져오는 것으로 시작됩니다.

여기에는 운영 체제와의 상호 작용을 위한 os, 상위 수준 파일 작업을 위한 quitil, 파일 비교를 위한 filecmp, 명령줄 인수 구문 분석을 위한 argparse, 긴 작업 중에 진행률 표시줄을 표시하기 위한 tqdm이 포함됩니다.

이러한 라이브러리는 함께 작동하여 디렉터리 동기화를 위한 강력한 솔루션을 만듭니다.

import os
import shutil
import filecmp
import argparse
from tqdm import tqdm

스크립트는 주로 Python 내장 모듈을 사용하지만 진행률 표시줄에는 다음과 함께 설치해야 하는 tqdmlibrary를 사용합니다.

pip install tqdm

디렉터리 확인 및 준비

동기화를 시작하기 전에 스크립트는 소스 디렉터리가 존재하는지 확인해야 합니다.

대상 디렉터리가 존재하지 않으면 스크립트가 디렉터리를 생성합니다.

이 단계는 디렉터리 누락으로 인한 문제 없이 동기화 프로세스가 원활하게 실행될 수 있도록 하는 데 중요합니다.

# Function to check if the source and destination directories exist
def check_directories(src_dir, dst_dir):
    # Check if the source directory exists
    if not os.path.exists(src_dir):
        print(f"\nSource directory '{src_dir}' does not exist.")
        return False
    # Create the destination directory if it does not exist
    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)
        print(f"\nDestination directory '{dst_dir}' created.")
    return True

check_directories 함수는 소스 및 대상 디렉토리가 모두 동기화할 준비가 되었는지 확인합니다. 작동 방식은 다음과 같습니다.

  • 이 함수는 os.path.exists()를 사용하여 디렉터리가 존재하는지 확인합니다.
  • 소스 디렉토리가 누락된 경우 스크립트는 사용자에게 이를 알리고 실행을 중지합니다.
  • 대상 디렉토리가 누락된 경우 스크립트는 os.makedirs()를 사용하여 자동으로 생성합니다. 이렇게 하면 필요한 디렉토리 구조가 제 위치에 있게 됩니다.

디렉터리 간 파일 동기화

스크립트의 주요 작업은 원본 디렉터리와 대상 디렉터리 간에 파일을 동기화하는 것입니다.

sync_directories 함수는 먼저 소스 디렉터리를 통해 모든 파일과 하위 디렉터리의 목록을 수집하여 이 작업을 처리합니다.

os.walk 함수는 디렉토리 트리에 파일 이름을 생성하여 스크립트가 소스 디렉토리 내의 모든 파일과 폴더를 캡처할 수 있도록 도와줍니다.

# Function to synchronize files between two directories
def sync_directories(src_dir, dst_dir, delete=False):
    # Get a list of all files and directories in the source directory
    files_to_sync = []
    for root, dirs, files in os.walk(src_dir):
        for directory in dirs:
            files_to_sync.append(os.path.join(root, directory))
        for file in files:
            files_to_sync.append(os.path.join(root, file))

    # Iterate over each file in the source directory with a progress bar
    with tqdm(total=len(files_to_sync), desc="Syncing files", unit="file") as pbar:
        # Iterate over each file in the source directory
        for source_path in files_to_sync:
            # Get the corresponding path in the replica directory
            replica_path = os.path.join(dst_dir, os.path.relpath(source_path, src_dir))

            # Check if path is a directory and create it in the replica directory if it does not exist
            if os.path.isdir(source_path):
                if not os.path.exists(replica_path):
                    os.makedirs(replica_path)
            # Copy all files from the source directory to the replica directory
            else:
                # Check if the file exists in the replica directory and if it is different from the source file
                if not os.path.exists(replica_path) or not filecmp.cmp(source_path, replica_path, shallow=False):
                    # Set the description of the progress bar and print the file being copied
                    pbar.set_description(f"Processing '{source_path}'")
                    print(f"\nCopying {source_path} to {replica_path}")

                    # Copy the file from the source directory to the replica directory
                    shutil.copy2(source_path, replica_path)

            # Update the progress bar
            pbar.update(1)

파일 및 디렉터리 목록이 컴파일되면 스크립트는 tqdm에서 제공하는 진행률 표시줄을 사용하여 사용자에게 동기화 프로세스에 대한 피드백을 제공합니다.

소스의 각 파일과 디렉터리에 대해 스크립트는 대상에서 해당 경로를 계산합니다.

경로가 디렉터리인 경우 스크립트는 디렉터리가 대상에 있는지 확인합니다.

경로가 파일인 경우 스크립트는 해당 파일이 대상에 이미 존재하는지, 소스 파일과 동일한지 확인합니다.

파일이 없거나 다른 경우 스크립트는 해당 파일을 대상에 복사합니다.

이런 식으로 스크립트는 대상 디렉토리를 소스 디렉토리와 최신 상태로 유지합니다.


추가 파일 정리

스크립트에는 원본 디렉터리에 없는 파일을 대상 디렉터리에서 삭제하는 선택적 기능도 있습니다.

이는 사용자가 설정할 수 있는 --delete 플래그로 제어됩니다.

이 플래그를 사용하면 스크립트는 대상 디렉터리를 통과하여 각 파일 및 폴더를 소스와 비교합니다.

소스에 없는 내용이 대상에서 발견되면 스크립트는 이를 삭제합니다.

이렇게 하면 대상 디렉토리가 소스 디렉토리의 정확한 복사본인지 확인할 수 있습니다.

# Clean up files in the destination directory that are not in the source directory, if delete flag is set
    if delete:
        # Get a list of all files in the destination directory
        files_to_delete = []
        for root, dirs, files in os.walk(dst_dir):
            for directory in dirs:
                files_to_delete.append(os.path.join(root, directory))
            for file in files:
                files_to_delete.append(os.path.join(root, file))

        # Iterate over each file in the destination directory with a progress bar
        with tqdm(total=len(files_to_delete), desc="Deleting files", unit="file") as pbar:
            # Iterate over each file in the destination directory
            for replica_path in files_to_delete:
                # Check if the file exists in the source directory
                source_path = os.path.join(src_dir, os.path.relpath(replica_path, dst_dir))
                if not os.path.exists(source_path):
                    # Set the description of the progress bar
                    pbar.set_description(f"Processing '{replica_path}'")
                    print(f"\nDeleting {replica_path}")

                    # Check if the path is a directory and remove it
                    if os.path.isdir(replica_path):
                        shutil.rmtree(replica_path)
                    else:
                        # Remove the file from the destination directory
                        os.remove(replica_path)

                # Update the progress bar
                pbar.update(1)

스크립트의 이 부분은 동기화 프로세스와 유사한 기술을 사용합니다.

os.walk()를 사용하여 파일과 디렉터리를 수집하고 tqdm을 사용하여 진행 상황을 표시합니다.
quitil.rmtree() 함수는 디렉토리를 제거하는 데 사용되는 반면 os.remove()는 개별 파일을 처리합니다.


스크립트 실행

이 스크립트는 원본 및 대상 디렉터리를 지정하는 인수를 사용하여 명령줄에서 실행되도록 설계되었습니다.

argparse 모듈을 사용하면 이러한 인수를 쉽게 처리할 수 있으므로 사용자는 스크립트를 실행할 때 필요한 경로와 옵션만 제공하면 됩니다.

# Main function to parse command line arguments and synchronize directories
if __name__ == "__main__":
    # Parse command line arguments
    parser = argparse.ArgumentParser(description="Synchronize files between two directories.")
    parser.add_argument("source_directory", help="The source directory to synchronize from.")
    parser.add_argument("destination_directory", help="The destination directory to synchronize to.")
    parser.add_argument("-d", "--delete", action="store_true",
                        help="Delete files in destination that are not in source.")
    args = parser.parse_args()

    # If the delete flag is set, print a warning message
    if args.delete:
        print("\nExtraneous files in the destination will be deleted.")

    # Check the source and destination directories
    if not check_directories(args.source_directory, args.destination_directory):
        exit(1)

    # Synchronize the directories
    sync_directories(args.source_directory, args.destination_directory, args.delete)
    print("\nSynchronization complete.")

주요 기능은 모든 것을 하나로 묶습니다.

명령줄 인수를 처리하고 디렉터리를 확인한 다음 동기화를 수행합니다.

--delete 플래그가 설정되면 추가 파일 정리도 처리합니다.


다양한 옵션을 사용하여 스크립트를 실행하는 방법에 대한 몇 가지 예를 살펴보겠습니다.

소스에서 대상으로

python file_sync.py d:\sync d:\sync_copy 
Destination directory 'd:\sync2' created.
Processing 'd:\sync\video.mp4':   0%|                                                                                                   | 0/5 [00:00<?, ?file/s]
Copying d:\sync\video.mp4 to d:\sync2\video.mp4
Processing 'd:\sync\video_final.mp4':  20%|██████████████████▌                                                                          | 1/5 [00:00<?, ?file/s] 
Copying d:\sync\video_final.mp4 to d:\sync2\video_final.mp4
Processing 'd:\sync\video_single - Copy (2).mp4':  40%|████████████████████████████████▍                                                | 2/5 [00:00<?, ?file/s] 
Copying d:\sync\video_single - Copy (2).mp4 to d:\sync2\video_single - Copy (2).mp4
Processing 'd:\sync\video_single - Copy.mp4':  60%|█████████████████████████████████████████████▌                              | 3/5 [00:00<00:00, 205.83file/s]
Copying d:\sync\video_single - Copy.mp4 to d:\sync2\video_single - Copy.mp4
Processing 'd:\sync\video_single.mp4':  80%|██████████████████████████████████████████████████████████████████▍                | 4/5 [00:00<00:00, 274.44file/s] 
Copying d:\sync\video_single.mp4 to d:\sync2\video_single.mp4
Processing 'd:\sync\video_single.mp4': 100%|███████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 343.05file/s] 

Synchronization complete.

Source to Destination with Cleanup of Extra Files

python file_sync.py d:\sync d:\sync_copy -d
Extraneous files in the destination will be deleted.
Syncing files: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 63.29file/s]
Deleting files: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<?, ?file/s] 

Synchronization complete.

Conclusion

This Python script offers a powerful and flexible way to synchronize files between two directories.

It uses key libraries like os, shutil, and filecmp, and enhances the user experience with tqdm for tracking progress.

This ensures that your data is consistently and efficiently synchronized.
Whether you're maintaining backups or ensuring consistency across storage locations, this script can be a valuable tool in your toolkit.

위 내용은 Python을 사용하여 두 디렉터리 간 파일 동기화의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.