130 lines
4.9 KiB
Python
130 lines
4.9 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""
|
||
文件复制工具:将源文件按奇/偶数编号复制到多个目录中。
|
||
|
||
用法:
|
||
python copy_files.py init # 初始化目录
|
||
python copy_files.py odd # 复制奇数编号文件 (1,3,5,...,119)
|
||
python copy_files.py even # 复制偶数编号文件 (2,4,6,...,120)
|
||
python copy_files.py clean # 清理生成的目录和源文件
|
||
|
||
兼容旧命令: js(=odd) / os(=even)
|
||
"""
|
||
import argparse
|
||
import shutil
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
# ===== 配置参数(可按需调整)=====
|
||
TOTAL_FILES = 120 # 文件总数 (1~120)
|
||
TOTAL_DIRS = 60 # 目标目录数 (1~60)
|
||
SOURCE_FILE = 'file.txt' # 源文件名
|
||
SOURCE_FILE_SIZE = 1*1024 * 1024 # 源文件不存在时自动生成的大小(字节,默认 1MB)
|
||
|
||
|
||
class FileCopier:
|
||
def __init__(self, ensure_source=True):
|
||
self.path = Path.cwd()
|
||
self.file_path = self.path / SOURCE_FILE
|
||
self.dir_list = list(range(1, TOTAL_DIRS + 1))
|
||
# clean 等清理操作不需要生成源文件
|
||
if ensure_source:
|
||
self._ensure_source_file()
|
||
|
||
def _ensure_source_file(self):
|
||
"""确保源文件存在:不存在则自动生成一个指定大小的占位文件。"""
|
||
if self.file_path.exists():
|
||
return
|
||
with self.file_path.open('wb') as f:
|
||
# 一次性写入全零字节,速度快且兼容大文件场景
|
||
f.write(b'\0' * SOURCE_FILE_SIZE)
|
||
print(f"源文件不存在,已自动生成 {self.file_path.name}({SOURCE_FILE_SIZE // 1024}KB)")
|
||
|
||
def init_dir(self):
|
||
"""初始化目录:删除已存在的同名目录后重新创建。"""
|
||
for dir_num in self.dir_list:
|
||
dir_path = self.path / str(dir_num)
|
||
if dir_path.exists():
|
||
shutil.rmtree(dir_path)
|
||
dir_path.mkdir(parents=True)
|
||
print(f"已初始化 {len(self.dir_list)} 个目录")
|
||
|
||
def clean(self):
|
||
"""清理:删除所有生成的目录(1~60)及源文件。"""
|
||
removed_dirs = 0
|
||
for dir_num in self.dir_list:
|
||
dir_path = self.path / str(dir_num)
|
||
if dir_path.exists():
|
||
shutil.rmtree(dir_path)
|
||
removed_dirs += 1
|
||
# 删除源文件
|
||
if self.file_path.exists():
|
||
self.file_path.unlink()
|
||
print(f"已删除源文件 {self.file_path.name}")
|
||
print(f"已清理 {removed_dirs} 个目录")
|
||
|
||
def _copy_files(self, file_list):
|
||
"""将源文件复制到各目录,文件名格式为 file_<编号>.txt。"""
|
||
# 源文件已在 __init__ 时确保存在;此处再校验以防外部删除
|
||
if not self.file_path.exists():
|
||
raise FileNotFoundError(f"源文件 {self.file_path} 不存在")
|
||
|
||
# 按顺序将文件分配到目录:file_list[i] -> dir_list[i]
|
||
file_dir_map = dict(zip(file_list, self.dir_list))
|
||
success_count = 0
|
||
|
||
for file_num, dir_num in file_dir_map.items():
|
||
target_path = self.path / str(dir_num) / f"file_{file_num}.txt"
|
||
try:
|
||
shutil.copyfile(self.file_path, target_path)
|
||
success_count += 1
|
||
except Exception as e:
|
||
print(f"复制文件 {file_num} 到目录 {dir_num} 失败: {e}")
|
||
|
||
print(f"成功复制 {success_count}/{len(file_list)} 个文件")
|
||
|
||
def copy_odd(self):
|
||
"""复制奇数编号文件 (1,3,5,...,119)。"""
|
||
file_list = list(range(1, TOTAL_FILES + 1, 2))
|
||
print(f"开始复制 {len(file_list)} 个奇数文件...")
|
||
self._copy_files(file_list)
|
||
|
||
def copy_even(self):
|
||
"""复制偶数编号文件 (2,4,6,...,120)。"""
|
||
file_list = list(range(2, TOTAL_FILES + 1, 2))
|
||
print(f"开始复制 {len(file_list)} 个偶数文件...")
|
||
self._copy_files(file_list)
|
||
|
||
|
||
def main():
|
||
parser = argparse.ArgumentParser(
|
||
description='文件复制工具:按奇/偶数编号复制源文件到多个目录',
|
||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||
epilog="兼容旧命令: js(=odd 奇数) / os(=even 偶数)"
|
||
)
|
||
parser.add_argument(
|
||
'command',
|
||
choices=['init', 'odd', 'even', 'clean', 'js', 'os'],
|
||
help='init: 初始化目录; odd/js: 复制奇数文件; even/os: 复制偶数文件; clean: 清理目录和源文件'
|
||
)
|
||
args = parser.parse_args()
|
||
|
||
# clean 命令不需要自动生成源文件
|
||
copier = FileCopier(ensure_source=(args.command != 'clean'))
|
||
try:
|
||
if args.command == 'init':
|
||
copier.init_dir()
|
||
elif args.command in ('odd', 'js'):
|
||
copier.copy_odd()
|
||
elif args.command in ('even', 'os'):
|
||
copier.copy_even()
|
||
elif args.command == 'clean':
|
||
copier.clean()
|
||
except Exception as e:
|
||
print(f"执行失败: {e}")
|
||
sys.exit(1)
|
||
|
||
|
||
if __name__ == '__main__':
|
||
main()
|