Typora 笔记迁移 Obsidian 图片附件库批量移动方法,适用于笔记整理。

news/2025/10/1 14:21:38/文章来源:https://www.cnblogs.com/zqingyang/p/19122419

附件:Typora 笔记迁移 Obsidian 图片附件库批量移动程序

需求

在ypora 笔记迁移 Obsidian 图片附件库过程中,之前的笔记都是采用的相对路径方法,而现在准备采用wiki索引方法,因此得检查不能是否冲突,对文件夹(含子文件夹)内的很多“Database”的附件文件夹进行操作。
将所有的“Database”内的所有文件移动到“DatabaseNew”中,如果遇到名称重复的。在该目标文件夹下自动新建的“Database重复文件手动处理”用于存放重复文件。将重复的文件移动到“Database重复文件手动处理”文件夹中。

思路

  • 文件聚合阶段:遍历所有名为 "Database" 的文件夹,将其中的文件移动到统一的新位置,并隔离出重名文件。

  • 清理阶段:删除所有已经变为空的 "Database" 文件夹,并报告所有未能清空的异常情况。

实践

备份整个目标文件夹,打压缩拷贝该文件夹副本进行操作。

参考目录

|-- 转换
|   |-- organize_db.py
|   `-- 综合软件使用教程 # 目标文件夹
|       |-- Database

安装python,网上教程很多,不再赘述。

  1. 保存脚本: 将下面的代码保存为一个 .py 文件,例如 organize_db.py

  2. 运行脚本: 打开终端或命令行工具,进入你保存脚本的目录,然后运行它:

      python .\organize_db.py
    

    程序会提示您输入笔记库的文件夹路径。只需将文件夹的绝对路径复制粘贴进去,然后按回车键即可。
    ![[Pasted image 20251001134623.png]]

  3. 检查结果: 脚本会自动扫描该文件夹及其所有子文件夹中的 Database 文件,将其中的文件移动到统一的新位置,并隔离出重名文件。可以在Database重复中查看是否有重复文件。
    ![[Pasted image 20251001134644.png]]

代码

import osimport sysimport shutildef organize_database_folders(root_folder):    """    1.  将所有 'Database' 子文件夹内的文件统一移动到 'DatabaseNew'。    2.  重名文件则移动到 'Database重复文件手动处理'。    3.  删除所有变为空的 'Database' 文件夹。    4.  报告未能删除的非空 'Database' 文件夹。    你可以进行替换Database为你要操作的文件夹!    """    # 3. 在目标文件夹下自动新建用于存放文件的文件夹    consolidate_dir = os.path.join(root_folder, "DatabaseNew")    duplicate_dir = os.path.join(root_folder, "Database重复文件手动处理")    try:        os.makedirs(consolidate_dir, exist_ok=True)        os.makedirs(duplicate_dir, exist_ok=True)        print(f"✔️ 目标文件夹创建/确认成功:\n  - {consolidate_dir}\n  - {duplicate_dir}")    except OSError as e:        print(f"❌ 错误: 无法创建目标文件夹,请检查权限。 {e}", file=sys.stderr)        return    moved_count = 0    duplicate_count = 0    # --- 阶段 1: 文件聚合 ---    print("\n--- 开始阶段 1: 移动文件 ---")    # 2. 扫描文件夹及文件    for dirpath, dirnames, filenames in os.walk(root_folder):        # 我们只关心名为 'Database' 的文件夹        if os.path.basename(dirpath) == "Database":            print(f"\n正在处理文件夹: {dirpath}")            for filename in filenames:                source_path = os.path.join(dirpath, filename)                dest_path_consolidate = os.path.join(consolidate_dir, filename)                # 4. 检查 'DatabaseNew' 中是否已存在同名文件                if not os.path.exists(dest_path_consolidate):                    # 不存在重名,移动到 'DatabaseNew'                    try:                        shutil.move(source_path, dest_path_consolidate)                        print(f"  -> 移动到 'DatabaseNew': {filename}")                        moved_count += 1                    except Exception as e:                        print(f"  ❌ 移动失败 (权限问题?): {filename} - {e}")                else:                    # 存在重名,移动到 'Database重复文件手动处理'                    dest_path_duplicate = os.path.join(duplicate_dir, filename)                    try:                        shutil.move(source_path, dest_path_duplicate)                        print(f"  ⚠️ 发现重复, 移动到 '重复文件' 文件夹: {filename}")                        duplicate_count += 1                    except Exception as e:                        print(f"  ❌ 移动重复文件失败: {filename} - {e}")    # --- 阶段 2: 清理空文件夹 ---    print("\n--- 开始阶段 2: 清理空的 'Database' 文件夹 ---")    deleted_folders_count = 0    non_empty_folders = []    # 使用 topdown=False, 从子文件夹向上遍历,这样才能成功删除空目录    for dirpath, _, _ in os.walk(root_folder, topdown=False):        # 5. 检查目标文件夹(含子文件夹),删除所有空的“Database”文件夹        if os.path.basename(dirpath) == "Database":            try:                # os.listdir() 会列出所有文件和子文件夹                if not os.listdir(dirpath):                    os.rmdir(dirpath)                    print(f"  🗑️ 删除空文件夹: {dirpath}")                    deleted_folders_count += 1                else:                    # 如果文件夹移动后仍不为空,记录下来                    non_empty_folders.append(dirpath)            except OSError as e:                print(f"  ❌ 删除文件夹失败: {dirpath} - {e}")                non_empty_folders.append(dirpath)    # --- 最终报告 ---    print("\n--- 操作摘要 ---")    print(f"移动到 'DatabaseNew' 的文件总数: {moved_count}")    print(f"因重名而移动到 'Database重复文件手动处理' 的文件总数: {duplicate_count}")    print(f"成功删除的空 'Database' 文件夹数量: {deleted_folders_count}")    if non_empty_folders:        print("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")        print("!!! 警告: 以下 'Database' 文件夹未能清空或删除,请手动检查。")        print("!!! 原因可能是权限不足,或文件夹内含有无法处理的隐藏文件/子文件夹。")        for path in non_empty_folders:            print(f"  - {path}")        print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")    else:        print("\n所有 'Database' 文件夹均已成功处理并清理。")# --- 主程序入口 ---if __name__ == "__main__":    target_folder = input("请输入要整理的根文件夹绝对路径并按 Enter: ")    target_folder = target_folder.strip().strip('"')    if os.path.isdir(target_folder):        print("-" * 60)        print(f"目标文件夹: {target_folder}")        print("此操作将执行以下任务:")        print("  1. 聚合所有 'Database' 文件夹内的文件到 'DatabaseNew'。")        print("  2. 隔离重名文件到 'Database重复文件手动处理'。")        print("  3. 删除所有清理完毕的空 'Database' 文件夹。")        print("\n警告: 文件移动是不可逆操作,建议在继续前备份您的文件夹。")        print("-" * 60)        confirm = input("确认要开始整理吗? (y/n): ")        if confirm.lower() == 'y':            organize_database_folders(target_folder)            print("\n所有操作已执行完毕。")        else:            print("操作已由用户取消。")    else:        print(f"错误: 您输入的路径 '{target_folder}' 不是一个有效的文件夹。", file=sys.stderr)
  • 创建目标目录: 首先使用 os.makedirs(exist_ok=True) 创建 DatabaseNewDatabase重复文件手动处理 文件夹,exist_ok=True 参数确保了即使文件夹已存在,程序也不会报错。

  • 第一次遍历 (文件移动): 使用 os.walk 遍历所有文件夹。当找到一个名为 Database 的目录时,就处理其中的所有文件。

    • 通过 os.path.exists 检查文件在 DatabaseNew 中是否已有同名文件。

    • 根据检查结果,使用 shutil.move 将文件移动到对应的目标位置。shutil.moveos.rename 更强大,可以跨磁盘移动文件。

  • 第二次遍历 (目录清理): 再次使用 os.walk,但这次加上了 topdown=False 参数。这使得遍历顺序从最深层的子目录开始,向上返回到根目录。这是删除空文件夹的关键,因为你必须先清空子目录才能删除父目录。

    • 通过 os.listdir(dirpath) 检查文件夹是否为空。

    • 如果为空,使用 os.rmdir(dirpath) 将其安全删除。此函数只能删除空目录,如果目录非空会报错,增加了安全性。

    • 如果目录非空或删除失败,就将其路径记录下来,在最后统一报告。

  • 统一报告: 在所有操作结束后,打印清晰的总结报告,让用户了解操作结果,特别是需要手动干预的异常情况。

注意事项

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/923930.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小学网站建设报告闵行网页设计培训学校

概念 A服务调用B服务,B服务调C服务,C服务调D服务,即微服务之间的通信(也可以叫微服务之间的调用) HTTP同步通信 一种轻量级的通信协议,常用于在不同的微服务之间进行通信,也是最简单的通信方式使用REST ful为开发规范,将服务对外暴露的HTTP调用方式为REST API(如GET…

2025年确有专长培训权威推荐榜:专业资质与特色诊疗口碑之选

2025年确有专长培训权威推荐榜:专业资质与特色诊疗口碑之选 中医药作为我国独特的医疗资源,近年来在政策支持与市场需求的双重推动下蓬勃发展。确有专长医师作为中医药服务体系中的重要组成部分,其专业能力与诊疗水…

开源 C# 快速构建(五)自定义控件--仪表盘

开源 C# 快速构建(五)自定义控件--仪表盘pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "…

2025中医师承培训、考试、认证机构权威推荐榜:名师传承与临床实践口碑之选

2025中医师承培训、考试、认证机构权威推荐榜:名师传承与临床实践口碑之选 在中医药事业蓬勃发展的今天,中医师承教育作为传统医学传承的重要方式,正受到越来越多从业者的关注与重视。随着国家对中医药传承创新支持…

建设监督网站阜城网站建设代理

1.筛选需求的报告id 基于REAC14Q4文件,筛选出需求报告的id,该文件格式如下,其中pt字段描述了患者在事件中所有的不良信息,注意此处一个报告id可以对应复数条信息。 primaryid$caseid$pt$drug_rec_act 初步统计约有4500种不良反应,总计60W条数…

什么网站做蔬菜生鲜比较好向客户介绍网站建设

一篇word文档,内容有大的章,小的节。如何把章节抽出来生成目录?WORD →点击需要插入的地方 → 插入菜单 → 索引和目录 → 目录 → 确定目录通常是长文档不可缺少的部分,有了目录,用户就能很容易地知道文档中有什么内容…

【Linux系列】让 Vim “跑”起来:建立一个会动的进度条

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

网上自己建网站网站建设合同建设方注意事项

来源:国防科技要闻据悉,俄罗斯地面部队已完成“木船”(Kungas)机器人系统样机的国家试验,将于2020年开始部署部队,用于作战试验。发展背景自2010年以来,俄罗斯机器人系统进入快速发展时期。2014…

网站空间商是什么图书馆网络规划与设计

Problem: 354. 俄罗斯套娃信封问题 文章目录 思路解题方法复杂度Code 思路 这个问题可以转换为最长递增子序列(Longest Increasing Subsequence,LIS)问题。先对信封按宽度升序排序,当宽度相同时,按高度降序排序。然后在…

天津建设工程评标专家网站怎么用ps制作个人网站模板下载

31.《危险化学品安全管理条例》所称重大危险源,是指生产、储存、使用或者搬运危险化学品,且危险化学品的数量等于或者超过()的单元(包括场所和设施)。 A.标准 B.一定量 C.临界量 答案:C 32.《危险化学品生产企业安全生产许可证实施办法》…

电子文件分类整理与双向同步 2025年10月1日

电子文件分类整理与双向同步 2025年10月1日一、网上包邮购买 极空间私有云Z4Pro+性能版钛金灰+希捷酷狼Pro16TBx4块二、在极空间Windows电脑客户端设置文件夹实时双向同步任务三、在极空间Windows电脑客户端设置自动挂…

手机wap购物网站模板上海建筑设计院招聘

内网工具对抗 首先,你需要分析: 1、安全工具是否有源代码 2、安全工具源代码逻辑复杂程度 3、当前源代码你是否有能力修改 其次,你需要考虑: 1、无源码或无能力修改 2、各种异常bug打包问题 3、修改打包后效果也不太好 故…

C++版搜索与图论算法 - 详解

C++版搜索与图论算法 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco",…

达成设计卓越:全面解析 IC 设计中的验证之道

在集成电路(IC)设计流程中,验证(Verification) 是确保设计符合规格、功能正确的关键环节。本文以简洁明快的风格,深入探讨验证的重要性、常用方法与实践经验,帮助设计师构建高效可靠的验证流程。 1、验证的重要…

Typora 笔记迁移 Obsidian 图片链接转换

解决了Typora 笔记迁移 Obsidian 图片链接转换问题,实现了自动化`![Pasted image 20221223164738.png](./Database/Pasted image 20221223164738.png)--![[Pasted image 20221223164738.png]]`附件:Typora 笔记迁移 O…

【Java八股文】12-分布式面试篇 - 教程

【Java八股文】12-分布式面试篇 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mon…

Java 运行 Word 文档标签并赋值:从基础到实战

Java 运行 Word 文档标签并赋值:从基础到实战pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &q…

上海配资网站开发广州开发区投资集团有限公司

都是copy的百度SDK文档,简单说说怎么用。1、没安装Python的参见此文:Python学习笔记系列 1 ——安装调试Python开发软件2、winr输入cmd打开命令行,输入:pip install baidu-aip,如下安装百度AI的模块。3、新建文本文档&…

词云组件

效果图: 组件代码:<template><div class="post"><div class="portal-title flex-h justify-between"><div class="flex-h"><img class="icon"…

域名 网站名称网站建设对电子商务的作用

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…