Python自动化大师第2篇:文件和文件夹自动化
Python Automation Master Part 2: File and Folder Automation
序言:文件自动化的必要性
在使用计算机时,我们会花费大量时间处理文件和文件夹。重命名数百个文件、查找并整理符合特定条件的文件、为备份复制文件等工作,如果手动操作既耗时又容易出错。
Python提供了强大的文件系统处理工具。在这一篇中,我们将学习如何使用Python的os、pathlib、shutil、glob模块高效地自动化文件和文件夹操作。
1. os模块基础
os模块是Python与操作系统交互的基本模块。它提供了文件系统操作必需的功能。
1.1 基本路径操作
import os
# 检查当前工作目录
current_dir = os.getcwd()
print(f"当前目录:{current_dir}")
# 更改工作目录
os.chdir("/path/to/directory")
# 访问环境变量
home_dir = os.environ.get('HOME') # Linux/Mac
user_profile = os.environ.get('USERPROFILE') # Windows
# 用户主目录(跨平台)
home = os.path.expanduser("~")
print(f"主目录:{home}")
1.2 路径操作
import os
# 路径连接(使用适合操作系统的分隔符)
full_path = os.path.join("folder", "subfolder", "file.txt")
print(full_path) # Windows: folder\subfolder\file.txt
# 路径分离
directory = os.path.dirname("/path/to/file.txt") # /path/to
filename = os.path.basename("/path/to/file.txt") # file.txt
# 分离文件名和扩展名
name, extension = os.path.splitext("document.pdf")
print(f"文件名:{name},扩展名:{extension}") # document, .pdf
# 获取绝对路径
abs_path = os.path.abspath("relative/path/file.txt")
# 检查路径是否存在
if os.path.exists("/path/to/check"):
print("路径存在。")
# 检查是文件还是文件夹
if os.path.isfile("/path/to/file.txt"):
print("是文件。")
if os.path.isdir("/path/to/folder"):
print("是文件夹。")
1.3 目录列表查询
import os
# 目录内项目列表
items = os.listdir("/path/to/directory")
print(items) # ['file1.txt', 'folder1', 'file2.py']
# 仅筛选文件
files = [f for f in os.listdir(".") if os.path.isfile(f)]
# 仅筛选文件夹
folders = [f for f in os.listdir(".") if os.path.isdir(f)]
# 仅筛选特定扩展名的文件
python_files = [f for f in os.listdir(".") if f.endswith(".py")]
1.4 目录遍历(os.walk)
import os
# 遍历所有子目录
for root, dirs, files in os.walk("/path/to/start"):
print(f"当前目录:{root}")
print(f"子文件夹:{dirs}")
print(f"文件:{files}")
print("-" * 50)
# 查找所有特定扩展名的文件
def find_files_by_extension(start_path, extension):
"""在指定路径中查找所有特定扩展名的文件。"""
found_files = []
for root, dirs, files in os.walk(start_path):
for file in files:
if file.endswith(extension):
full_path = os.path.join(root, file)
found_files.append(full_path)
return found_files
# 查找所有.txt文件
txt_files = find_files_by_extension(".", ".txt")
for f in txt_files:
print(f)
2. pathlib模块使用
pathlib是Python 3.4引入的面向对象的文件系统路径库。比os.path更直观、更现代化地处理路径。
2.1 Path对象基础
from pathlib import Path
# 创建Path对象
p = Path("/path/to/file.txt")
current = Path(".")
home = Path.home()
# 路径连接(使用/运算符)
full_path = Path.home() / "Documents" / "project" / "file.txt"
print(full_path)
# 路径属性
print(p.name) # file.txt(文件名)
print(p.stem) # file(不含扩展名的文件名)
print(p.suffix) # .txt(扩展名)
print(p.parent) # /path/to(父目录)
print(p.parts) # ('/', 'path', 'to', 'file.txt')
# 绝对路径
abs_path = Path("relative/path").resolve()
# 检查是否存在
if p.exists():
print("存在。")
if p.is_file():
print("是文件。")
if p.is_dir():
print("是目录。")
2.2 目录探索
from pathlib import Path
# 当前目录的所有项目
for item in Path(".").iterdir():
print(item)
# 特定模式匹配(仅当前目录)
for py_file in Path(".").glob("*.py"):
print(py_file)
# 递归模式匹配(所有子目录)
for py_file in Path(".").rglob("*.py"):
print(py_file)
# 搜索多个扩展名
extensions = ["*.jpg", "*.png", "*.gif"]
images = []
for ext in extensions:
images.extend(Path(".").rglob(ext))
# 仅筛选文件
files_only = [p for p in Path(".").iterdir() if p.is_file()]
# 仅筛选文件夹
dirs_only = [p for p in Path(".").iterdir() if p.is_dir()]
2.3 文件/文件夹创建和删除
from pathlib import Path
# 创建目录
new_dir = Path("new_folder")
new_dir.mkdir(exist_ok=True) # 即使已存在也不报错
# 创建嵌套目录
nested_dir = Path("parent/child/grandchild")
nested_dir.mkdir(parents=True, exist_ok=True)
# 创建文件(空文件)
new_file = Path("new_file.txt")
new_file.touch()
# 删除文件
if new_file.exists():
new_file.unlink()
# 删除空目录
if new_dir.exists() and new_dir.is_dir():
new_dir.rmdir() # 目录必须为空
# 重命名文件
old_path = Path("old_name.txt")
new_path = Path("new_name.txt")
if old_path.exists():
old_path.rename(new_path)
3. 文件读写
了解Python中读写文件的方法。使用with语句可以自动关闭文件,因此推荐使用。
3.1 文本文件处理
# 写入文件
with open("example.txt", "w", encoding="utf-8") as f:
f.write("第一行\n")
f.write("第二行\n")
# 追加内容到文件
with open("example.txt", "a", encoding="utf-8") as f:
f.write("追加的行\n")
# 读取文件(全部)
with open("example.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
# 读取文件(逐行)
with open("example.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip()) # 去除换行符
# 读取文件(转为列表)
with open("example.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
print(lines) # ['第一行\n', '第二行\n', ...]
# 一次性写入多行
lines_to_write = ["行1\n", "行2\n", "行3\n"]
with open("output.txt", "w", encoding="utf-8") as f:
f.writelines(lines_to_write)
3.2 使用pathlib读写文件
from pathlib import Path
# 简便的文件写入
Path("simple.txt").write_text("Hello, World!", encoding="utf-8")
# 简便的文件读取
content = Path("simple.txt").read_text(encoding="utf-8")
print(content)
# 读取二进制文件
binary_content = Path("image.png").read_bytes()
# 写入二进制文件
Path("copy.png").write_bytes(binary_content)
3.3 CSV文件处理
import csv
# 写入CSV
data = [
["姓名", "年龄", "城市"],
["张三", 30, "北京"],
["李四", 25, "上海"],
["王五", 28, "广州"]
]
with open("data.csv", "w", newline="", encoding="utf-8-sig") as f:
writer = csv.writer(f)
writer.writerows(data)
# 读取CSV
with open("data.csv", "r", encoding="utf-8-sig") as f:
reader = csv.reader(f)
for row in reader:
print(row)
# 使用字典处理CSV
with open("data.csv", "r", encoding="utf-8-sig") as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['姓名']}今年{row['年龄']}岁。")
3.4 JSON文件处理
import json
# 写入JSON
data = {
"name": "张三",
"age": 30,
"skills": ["Python", "JavaScript", "SQL"],
"address": {
"city": "北京",
"district": "朝阳区"
}
}
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# 读取JSON
with open("data.json", "r", encoding="utf-8") as f:
loaded_data = json.load(f)
print(loaded_data["name"])
print(loaded_data["skills"])
4. 文件夹创建/删除/移动
4.1 创建文件夹
import os
from pathlib import Path
# 使用os创建文件夹
os.makedirs("parent/child/grandchild", exist_ok=True)
# 使用pathlib创建文件夹
Path("another/nested/folder").mkdir(parents=True, exist_ok=True)
# 创建按日期命名的文件夹
from datetime import datetime
today = datetime.now().strftime("%Y-%m-%d")
daily_folder = Path("backups") / today
daily_folder.mkdir(parents=True, exist_ok=True)
4.2 删除文件夹
import os
import shutil
from pathlib import Path
# 删除空文件夹
os.rmdir("empty_folder")
# 或者
Path("empty_folder").rmdir()
# 删除有内容的文件夹(注意:无法恢复!)
shutil.rmtree("folder_with_contents")
# 安全删除(确认后删除)
def safe_delete_folder(folder_path):
"""安全地删除文件夹。"""
path = Path(folder_path)
if not path.exists():
print(f"'{folder_path}'不存在。")
return False
# 检查文件夹内容
items = list(path.rglob("*"))
file_count = sum(1 for item in items if item.is_file())
folder_count = sum(1 for item in items if item.is_dir())
print(f"要删除的文件夹:{folder_path}")
print(f"包含的文件:{file_count}个")
print(f"包含的文件夹:{folder_count}个")
confirm = input("确定要删除吗?(yes/no):")
if confirm.lower() == "yes":
shutil.rmtree(path)
print("删除完成!")
return True
else:
print("已取消。")
return False
5. 文件搜索(glob)
glob模块使用Unix shell风格的模式匹配来搜索文件。
5.1 glob基本用法
import glob
# 当前目录的所有.txt文件
txt_files = glob.glob("*.txt")
# 特定文件夹的所有.py文件
py_files = glob.glob("src/*.py")
# 递归搜索(所有子文件夹)
all_py_files = glob.glob("**/*.py", recursive=True)
# 搜索多个扩展名
import itertools
extensions = ["*.jpg", "*.png", "*.gif"]
images = list(itertools.chain.from_iterable(
glob.glob(ext, recursive=True) for ext in ["**/" + e for e in extensions]
))
# 模式匹配示例
# ? : 单个字符
# * : 任意字符(0个或多个)
# [abc] : a、b、c中的一个
# [0-9] : 数字
files = glob.glob("file?.txt") # file1.txt, fileA.txt
files = glob.glob("data[0-9].csv") # data0.csv ~ data9.csv
files = glob.glob("[!_]*.py") # 不以下划线开头的.py文件
5.2 pathlib的glob
from pathlib import Path
# 在当前目录搜索
for txt_file in Path(".").glob("*.txt"):
print(txt_file)
# 递归搜索
for py_file in Path(".").rglob("*.py"):
print(py_file)
# 复杂模式
for file in Path("data").glob("**/report_*.xlsx"):
print(file)
6. 文件复制/移动(shutil)
shutil模块提供文件和文件夹的高级操作(复制、移动、删除)功能。
6.1 文件复制
import shutil
# 复制文件(不含元数据)
shutil.copy("source.txt", "destination.txt")
# 复制文件(含元数据)
shutil.copy2("source.txt", "destination.txt")
# 复制到文件夹(保留原文件名)
shutil.copy("source.txt", "backup_folder/")
# 复制整个文件夹
shutil.copytree("source_folder", "destination_folder")
# 排除特定文件复制
def ignore_patterns(directory, files):
"""忽略特定模式的文件。"""
return [f for f in files if f.endswith('.pyc') or f.startswith('.')]
shutil.copytree("source", "dest", ignore=ignore_patterns)
# 或使用内置函数
shutil.copytree("source", "dest",
ignore=shutil.ignore_patterns('*.pyc', '*.tmp', '__pycache__'))
6.2 文件移动
import shutil
# 移动文件
shutil.move("source.txt", "new_location/source.txt")
# 重命名文件(在同一文件夹内移动)
shutil.move("old_name.txt", "new_name.txt")
# 移动文件夹
shutil.move("source_folder", "new_location/")
# 安全移动函数
from pathlib import Path
def safe_move(source, destination):
"""安全地移动文件。"""
src = Path(source)
dst = Path(destination)
if not src.exists():
print(f"源文件'{source}'不存在。")
return False
# 如果目标是文件夹,保留源文件名
if dst.is_dir():
dst = dst / src.name
# 如果目标已存在则确认
if dst.exists():
confirm = input(f"'{dst}'已存在。是否覆盖?(y/n):")
if confirm.lower() != 'y':
print("已取消。")
return False
shutil.move(str(src), str(dst))
print(f"'{source}' -> '{dst}' 移动完成")
return True
7. 批量重命名文件
批量重命名文件是自动化的典型应用场景。
7.1 基本文件名更改
import os
from pathlib import Path
# 添加前缀
def add_prefix(folder, prefix):
"""为文件夹内所有文件添加前缀。"""
folder_path = Path(folder)
for file in folder_path.iterdir():
if file.is_file():
new_name = folder_path / f"{prefix}{file.name}"
file.rename(new_name)
print(f"'{file.name}' -> '{new_name.name}'")
# 添加后缀
def add_suffix(folder, suffix):
"""为文件名添加后缀(扩展名前)。"""
folder_path = Path(folder)
for file in folder_path.iterdir():
if file.is_file():
new_name = folder_path / f"{file.stem}{suffix}{file.suffix}"
file.rename(new_name)
print(f"'{file.name}' -> '{new_name.name}'")
7.2 按序号重命名文件
from pathlib import Path
def rename_with_sequence(folder, base_name, start=1, padding=3):
"""将文件名更改为序号。
例:image_001.jpg, image_002.jpg, ...
"""
folder_path = Path(folder)
files = sorted([f for f in folder_path.iterdir() if f.is_file()])
for i, file in enumerate(files, start=start):
# 格式化序号(001, 002, ...)
sequence = str(i).zfill(padding)
new_name = folder_path / f"{base_name}_{sequence}{file.suffix}"
file.rename(new_name)
print(f"'{file.name}' -> '{new_name.name}'")
7.3 基于日期重命名文件
from pathlib import Path
from datetime import datetime
import os
def rename_with_date(folder, include_time=False):
"""根据文件的修改日期重命名。"""
folder_path = Path(folder)
for file in folder_path.iterdir():
if file.is_file():
# 获取文件修改时间
mtime = os.path.getmtime(file)
date_obj = datetime.fromtimestamp(mtime)
if include_time:
date_str = date_obj.strftime("%Y%m%d_%H%M%S")
else:
date_str = date_obj.strftime("%Y%m%d")
new_name = folder_path / f"{date_str}_{file.name}"
# 防止重复
counter = 1
while new_name.exists():
new_name = folder_path / f"{date_str}_{counter}_{file.name}"
counter += 1
file.rename(new_name)
print(f"'{file.name}' -> '{new_name.name}'")
7.4 使用正则表达式重命名文件
import re
from pathlib import Path
def rename_with_regex(folder, pattern, replacement):
"""使用正则表达式更改文件名。"""
folder_path = Path(folder)
for file in folder_path.iterdir():
if file.is_file():
new_name = re.sub(pattern, replacement, file.stem)
if new_name != file.stem:
new_path = folder_path / f"{new_name}{file.suffix}"
file.rename(new_path)
print(f"'{file.name}' -> '{new_path.name}'")
# 使用示例
# 将空格替换为下划线
rename_with_regex(".", r"\s+", "_")
# 删除特殊字符
rename_with_regex(".", r"[^\w\-_.]", "")
8. 查找重复文件
为了节省硬盘空间,我们来编写一个查找和整理重复文件的脚本。
import hashlib
from pathlib import Path
from collections import defaultdict
def get_file_hash(filepath, chunk_size=8192):
"""计算文件的MD5哈希值。"""
hasher = hashlib.md5()
with open(filepath, 'rb') as f:
while chunk := f.read(chunk_size):
hasher.update(chunk)
return hasher.hexdigest()
def find_duplicates(folder):
"""查找文件夹内的重复文件。"""
folder_path = Path(folder)
# 第1步:按文件大小分组
size_dict = defaultdict(list)
for file in folder_path.rglob("*"):
if file.is_file():
size_dict[file.stat().st_size].append(file)
# 第2步:只比较相同大小文件的哈希
hash_dict = defaultdict(list)
for size, files in size_dict.items():
if len(files) > 1: # 只有相同大小的文件有2个以上时
for file in files:
file_hash = get_file_hash(file)
hash_dict[file_hash].append(file)
# 第3步:筛选重复文件
duplicates = {h: files for h, files in hash_dict.items() if len(files) > 1}
return duplicates
def report_duplicates(folder):
"""输出重复文件报告。"""
duplicates = find_duplicates(folder)
if not duplicates:
print("没有重复文件。")
return
total_wasted = 0
print("=" * 60)
print("重复文件报告")
print("=" * 60)
for hash_value, files in duplicates.items():
file_size = files[0].stat().st_size
wasted = file_size * (len(files) - 1)
total_wasted += wasted
print(f"\n哈希:{hash_value[:16]}...")
print(f"文件大小:{file_size:,} bytes")
print(f"重复数量:{len(files)}个")
print("文件列表:")
for f in files:
print(f" - {f}")
print("\n" + "=" * 60)
print(f"总浪费空间:{total_wasted:,} bytes ({total_wasted / 1024 / 1024:.2f} MB)")
print("=" * 60)
def delete_duplicates(folder, keep='first'):
"""删除重复文件。
Args:
folder: 目标文件夹
keep: 'first'(保留第一个)或 'newest'(保留最新文件)
"""
duplicates = find_duplicates(folder)
deleted_count = 0
freed_space = 0
for hash_value, files in duplicates.items():
if keep == 'newest':
# 按修改时间排序(最新的在前)
files = sorted(files, key=lambda f: f.stat().st_mtime, reverse=True)
# 保留第一个文件,删除其余的
for file in files[1:]:
file_size = file.stat().st_size
print(f"删除:{file}")
file.unlink()
deleted_count += 1
freed_space += file_size
print(f"\n删除的文件:{deleted_count}个")
print(f"释放的空间:{freed_space:,} bytes ({freed_space / 1024 / 1024:.2f} MB)")
9. 文件整理自动化项目
让我们综合到目前为止学到的内容,创建一个实用的文件整理自动化项目。
"""
高级文件整理自动化脚本
- 按扩展名分类
- 按日期分类
- 按大小分类
- 处理重复文件
- 支持日志
"""
import os
import shutil
import hashlib
import logging
from pathlib import Path
from datetime import datetime
from collections import defaultdict
# 日志设置
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('file_organizer.log', encoding='utf-8'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
# 扩展名到类别的映射
CATEGORIES = {
'Images': ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp', '.ico'],
'Documents': ['.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.txt', '.rtf', '.odt'],
'Videos': ['.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv', '.webm'],
'Music': ['.mp3', '.wav', '.flac', '.aac', '.ogg', '.wma', '.m4a'],
'Archives': ['.zip', '.rar', '.7z', '.tar', '.gz', '.bz2'],
'Programs': ['.exe', '.msi', '.dmg', '.deb', '.rpm', '.apk'],
'Code': ['.py', '.js', '.html', '.css', '.java', '.cpp', '.c', '.h', '.json', '.xml'],
'Data': ['.csv', '.sql', '.db', '.sqlite']
}
def get_category(extension):
"""返回扩展名对应的类别。"""
ext_lower = extension.lower()
for category, extensions in CATEGORIES.items():
if ext_lower in extensions:
return category
return 'Others'
def get_file_hash(filepath):
"""计算文件的MD5哈希。"""
hasher = hashlib.md5()
with open(filepath, 'rb') as f:
for chunk in iter(lambda: f.read(8192), b''):
hasher.update(chunk)
return hasher.hexdigest()
class FileOrganizer:
def __init__(self, source_folder, dest_folder=None):
self.source = Path(source_folder)
self.dest = Path(dest_folder) if dest_folder else self.source
self.stats = {
'moved': 0,
'skipped': 0,
'duplicates': 0,
'errors': 0
}
self.hash_dict = defaultdict(list)
def organize_by_extension(self):
"""按扩展名整理文件。"""
logger.info(f"开始按扩展名整理:{self.source}")
for file in self.source.iterdir():
if file.is_file():
category = get_category(file.suffix)
target_folder = self.dest / category
target_folder.mkdir(exist_ok=True)
target_path = target_folder / file.name
# 处理重复文件名
if target_path.exists():
target_path = self._get_unique_path(target_path)
try:
shutil.move(str(file), str(target_path))
logger.info(f"移动:{file.name} -> {category}/")
self.stats['moved'] += 1
except Exception as e:
logger.error(f"错误:{file.name} - {e}")
self.stats['errors'] += 1
self._print_stats()
def organize_by_date(self, date_format="%Y-%m"):
"""按修改日期整理文件。"""
logger.info(f"开始按日期整理:{self.source}")
for file in self.source.iterdir():
if file.is_file():
mtime = datetime.fromtimestamp(file.stat().st_mtime)
date_folder = mtime.strftime(date_format)
target_folder = self.dest / date_folder
target_folder.mkdir(exist_ok=True)
target_path = target_folder / file.name
if target_path.exists():
target_path = self._get_unique_path(target_path)
try:
shutil.move(str(file), str(target_path))
logger.info(f"移动:{file.name} -> {date_folder}/")
self.stats['moved'] += 1
except Exception as e:
logger.error(f"错误:{file.name} - {e}")
self.stats['errors'] += 1
self._print_stats()
def organize_by_size(self, thresholds=None):
"""按大小整理文件。"""
if thresholds is None:
thresholds = {
'Tiny (< 100KB)': 100 * 1024,
'Small (100KB - 1MB)': 1024 * 1024,
'Medium (1MB - 100MB)': 100 * 1024 * 1024,
'Large (100MB - 1GB)': 1024 * 1024 * 1024,
'Huge (> 1GB)': float('inf')
}
logger.info(f"开始按大小整理:{self.source}")
for file in self.source.iterdir():
if file.is_file():
size = file.stat().st_size
for category, threshold in thresholds.items():
if size < threshold:
target_folder = self.dest / category
break
target_folder.mkdir(exist_ok=True)
target_path = target_folder / file.name
if target_path.exists():
target_path = self._get_unique_path(target_path)
try:
shutil.move(str(file), str(target_path))
logger.info(f"移动:{file.name} ({size:,} bytes) -> {category}/")
self.stats['moved'] += 1
except Exception as e:
logger.error(f"错误:{file.name} - {e}")
self.stats['errors'] += 1
self._print_stats()
def find_and_handle_duplicates(self, action='report'):
"""查找并处理重复文件。
Args:
action: 'report'(仅报告), 'move'(移动到单独文件夹), 'delete'(删除)
"""
logger.info(f"开始搜索重复文件:{self.source}")
# 计算文件哈希
for file in self.source.rglob("*"):
if file.is_file():
try:
file_hash = get_file_hash(file)
self.hash_dict[file_hash].append(file)
except Exception as e:
logger.error(f"哈希计算错误:{file} - {e}")
# 处理重复文件
duplicates_folder = self.dest / "Duplicates"
for hash_value, files in self.hash_dict.items():
if len(files) > 1:
logger.info(f"发现重复:{len(files)}个文件")
# 保留第一个文件
original = files[0]
for dup in files[1:]:
self.stats['duplicates'] += 1
if action == 'report':
logger.info(f" 重复:{dup}(原始:{original})")
elif action == 'move':
duplicates_folder.mkdir(exist_ok=True)
target = duplicates_folder / dup.name
if target.exists():
target = self._get_unique_path(target)
shutil.move(str(dup), str(target))
logger.info(f" 移动:{dup} -> Duplicates/")
elif action == 'delete':
dup.unlink()
logger.info(f" 删除:{dup}")
self._print_stats()
def _get_unique_path(self, path):
"""返回不重复的文件路径。"""
counter = 1
new_path = path
while new_path.exists():
new_path = path.parent / f"{path.stem}_{counter}{path.suffix}"
counter += 1
return new_path
def _print_stats(self):
"""输出统计信息。"""
logger.info("=" * 50)
logger.info("处理结果:")
logger.info(f" 移动的文件:{self.stats['moved']}个")
logger.info(f" 跳过的文件:{self.stats['skipped']}个")
logger.info(f" 重复文件:{self.stats['duplicates']}个")
logger.info(f" 错误:{self.stats['errors']}个")
logger.info("=" * 50)
def main():
"""主执行函数"""
print("=" * 60)
print("高级文件整理自动化")
print("=" * 60)
source = input("要整理的文件夹路径:").strip()
if not source:
source = str(Path.home() / "Downloads")
print(f"使用默认路径:{source}")
print("\n请选择整理方式:")
print("1. 按扩展名整理")
print("2. 按日期整理")
print("3. 按大小整理")
print("4. 查找重复文件")
print("5. 执行所有整理")
choice = input("\n选择(1-5):").strip()
organizer = FileOrganizer(source)
if choice == '1':
organizer.organize_by_extension()
elif choice == '2':
organizer.organize_by_date()
elif choice == '3':
organizer.organize_by_size()
elif choice == '4':
action = input("重复文件处理方式(report/move/delete):").strip()
organizer.find_and_handle_duplicates(action or 'report')
elif choice == '5':
organizer.find_and_handle_duplicates('move')
organizer.organize_by_extension()
else:
print("无效的选择。")
if __name__ == "__main__":
main()
10. 总结与下一篇预告
在这一篇中,我们学习了使用Python进行文件和文件夹自动化的核心技术:
- 使用os模块进行基本文件系统操作
- 使用pathlib进行面向对象的路径处理
- 文件读写(文本、CSV、JSON)
- 文件夹创建、删除、移动
- 使用glob进行文件搜索
- 使用shutil进行文件复制/移动
- 批量重命名文件技术
- 查找和处理重复文件
- 综合文件整理自动化项目
这些知识将成为今后各种自动化项目的基础。如果能够自如地处理文件系统,就可以实现备份自动化、日志分析、数据预处理等无限可能的应用。
下一篇预告:在Python自动化大师第3篇中,我们将学习网页爬虫自动化。使用requests、BeautifulSoup、Selenium自动从网页收集数据的方法!