批量将含文件的子目录迁移至根目录并保留指定结构
批量迁移子目录至根目录(保留首个含文件子目录结构)
需求说明
- 目标:将包含文件的整个子目录迁移到根目录,删除根目录与首个含文件子目录之间的所有空目录,保留该子目录及其以下的完整结构
- 注意事项:文件名、文件夹名可能包含非ASCII字符;首个含文件的子目录距离根目录至少有3层
原目录结构
Root | Sub 1 > Sub 2 > Sub 3 > A. files and subfolders > Sub > Sub Root | Sub 4 > Sub 5 > B. file, E. file Root | Sub 6 > Sub 7 > Sub 8 > Sub 9 > C. file and subfolders > Sub > Sub > Sub > Sub > D. file
目标目录结构
Root | Sub 3 > A. files and subfolders > Sub > Sub Root | Sub 5 > B. file, E. file Root | Sub 9 > C. file and subfolders > Sub > Sub > Sub > Sub > D. file
解决方案
Python 脚本(跨平台,支持非ASCII字符)
以下脚本会自动遍历根目录,定位每个分支里首个含文件的子目录,将其移动到根目录,并清理中间的空目录:
import os import shutil def find_first_non_empty_dir(start_path): """递归查找首个包含文件的子目录""" for root, dirs, files in os.walk(start_path): if files: return root for d in dirs: res = find_first_non_empty_dir(os.path.join(root, d)) if res: return res return None def move_and_clean(root_dir): for entry in os.scandir(root_dir): if not entry.is_dir(): continue first_non_empty = find_first_non_empty_dir(entry.path) if not first_non_empty: continue # 处理重名目录 target_dir = os.path.join(root_dir, os.path.basename(first_non_empty)) counter = 1 while os.path.exists(target_dir): target_dir = os.path.join(root_dir, f"{os.path.basename(first_non_empty)}_{counter}") counter += 1 # 移动目录 shutil.move(first_non_empty, target_dir) print(f"已移动: {first_non_empty} -> {target_dir}") # 清理空目录 current_dir = os.path.dirname(first_non_empty) while current_dir != root_dir: if not os.listdir(current_dir): os.rmdir(current_dir) print(f"已删除空目录: {current_dir}") current_dir = os.path.dirname(current_dir) if __name__ == "__main__": # 替换为你的根目录实际路径 ROOT_DIRECTORY = "/path/to/your/Root" move_and_clean(ROOT_DIRECTORY)
使用说明
- 将
ROOT_DIRECTORY替换为你的根目录路径 - 运行前建议备份数据,避免意外
- 脚本自动兼容含非ASCII字符的目录/文件名
Shell 脚本(Linux/macOS)
适用于类Unix系统,需确保系统支持UTF-8字符处理:
#!/bin/bash ROOT_DIR="/path/to/your/Root" export LC_ALL=C.UTF-8 for dir in "$ROOT_DIR"/*/; do # 找到首个包含文件的子目录 first_non_empty=$(find "$dir" -type f -printf "%h\n" | head -n 1) if [ -z "$first_non_empty" ]; then continue fi # 处理重名 target_name=$(basename "$first_non_empty") target_path="$ROOT_DIR/$target_name" counter=1 while [ -d "$target_path" ]; do target_path="$ROOT_DIR/${target_name}_$counter" counter=$((counter+1)) done # 移动目录 mv "$first_non_empty" "$target_path" echo "已移动: $first_non_empty -> $target_path" # 清理空目录 current_dir=$(dirname "$first_non_empty") while [ "$current_dir" != "$ROOT_DIR" ]; do if [ -z "$(ls -A "$current_dir")" ]; then rmdir "$current_dir" echo "已删除空目录: $current_dir" fi current_dir=$(dirname "$current_dir") done done
Shell 脚本使用说明
- 修改
ROOT_DIR为你的根目录路径 - 赋予脚本执行权限:
chmod +x move_dirs.sh - 运行脚本:
./move_dirs.sh
内容的提问来源于stack exchange,提问作者vav
相关产品推荐
相关产品推荐

