用 Python pathlib 统计文件扩展名:先明确目录、后缀和链接的边界
整理下载目录前,先做一份文件类型清单,往往比直接批量移动更容易核对。本文用 Python 标准库写一个只读的小工具:按扩展名统计目录第一层的普通文件,输出每类数量。它只查询目录项,不读取文件正文,也不移动或删除文件,适合用作自动归档前的预览步骤。
先定义统计口径
统计口径决定结果是否可信。本例不递归进入子目录,显式跳过符号链接,并把后缀转为小写,因此 a.txt 和 B.TXT 会归到同一类。没有后缀的文件放进“[无扩展名]”。这些都是本工具的业务选择;如果希望保留大小写差异,可以去掉 lower()。
扩展名也不等于真实文件类型。把一张图片改名为 photo.txt,不会改变它的内部格式。这里得到的是文件名后缀分布,不能拿它代替文件格式检测,更不能据此判断文件是否安全。
可运行代码
将下面代码保存为 count_extensions.py,使用 python3 count_extensions.py "demo" 运行。命令中的 demo 是你自己的待统计目录,路径包含空格时保留引号。代码只依赖 Python 标准库。
from collections import Counter
from pathlib import Path
def count_extensions(folder):
counts = Counter()
for item in Path(folder).iterdir():
if item.is_symlink():
continue
if item.is_file():
suffix = item.suffix.lower() or "[无扩展名]"
counts[suffix] += 1
return counts
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="统计目录第一层的文件扩展名")
parser.add_argument("folder", type=Path)
args = parser.parse_args()
try:
counts = count_extensions(args.folder)
except OSError as error:
parser.exit(1, f"统计失败:{error}\n")
for suffix, number in sorted(counts.items()):
print(f"{suffix}: {number}")
用小样本核对结果
创建一个 demo 目录,在第一层放入 a.txt、B.TXT、notes.md、archive.tar.gz、README 和 .env,再创建 subfolder 子目录,并在里面放 nested.txt。运行后应得到以下结果;子目录中的 nested.txt 不参与统计。
.gz: 1
.md: 1
.txt: 2
[无扩展名]: 2
这里有两个容易忽略的细节:archive.tar.gz 的最后一个后缀是 .gz;单独的点文件 .env 在本例中归为无扩展名。若要把 .tar.gz 作为整体,需要制定复合后缀规则,例如先检查已知的复合后缀,再回退到最后一个后缀;不要直接把所有点号后的文字都拼起来。
异常与边界
输入不存在、输入实际是文件,或者遍历目录时遇到会抛出的系统错误,程序会输出“统计失败”并以非零状态退出。这能避免把失败误报为空目录。但文件系统会变化:统计期间新增、删除或改名的文件可能影响结果,部分元数据查询失败也可能表现为无法确认普通文件。因此这份清单不是事务快照,也不用于权限审计。
本文代码已用临时目录核对上述六个文件的数量、子目录不递归、符号链接跳过,以及不存在目录时的失败退出。实际使用时,建议先在少量样本上确认统计口径,再扩展到递归或导出 CSV;扩展时仍应保留只读预览,等人核对后再执行归档。
参考:Python 官方 pathlib 文档,https://docs.python.org/zh-cn/3/library/pathlib.html 。本文说明和代码示例为本次独立编写。
- 点赞
- 收藏
- 关注作者
评论(0)