obsidian将图片附件从固定文件夹中分别移动到指定的文件夹中

NOTE
数据无价!数据无价!数据无价!
使用该脚本前先将自己的需要调整的库拷贝一份!!!

应用背景和条件

由于以前用obsidian写文档时都专注于方便自己来记笔记,因此在设置附件位置时图简洁就将所有图片文件都放到了顶层的附件文件夹中,但是最近我想将自己的部分笔记分享出来(使用docsify)就发现了obsidian里面的图片插入默认是obsidian的简短形式,而且由于我的附件位置就在顶层,这就导致了我在推送自己的文件时没法将图片直接简单的上传,而且这样与markdown的标准写法不同,这就导致别的markdown软件无法识别,这就很恼火了。由于图片文件过多,因此用python写了一个简单的脚本来将文档中的图片放到指定的位置并修改图片引入的方式。

请确保你的情况与我的基本一致在执行下文代码,我没有将所有的情况都考虑进去,只针对了我的情况。由于我前面遇到那个问题,因此我使用了插件Custom Attachment location来管理我后续的图片引入方式,因此脚本是针对下述插件配置的。

在这里插入图片描述

其他原仓库配置如下。

  • 顶层文件位置

在这里插入图片描述

  • 内部图片引入方式

在这里插入图片描述

  • 整体仓库样式

在这里插入图片描述

如果你的环境和我的基本一致,那么你就先测试一下脚本吧,不一致你可以改我的脚本,要不就快点寻找其他办法吧。

脚本代码

注意执行前备份仓库,数据无价!!!

import os
import re
import shutil
from tqdm import tqdm

# ======================================
# = config =
obsidianVault = 'C:\\Projects\\OB\\test'
accessoryPath = 'assets'
imagesPath = 'C:\\Projects\\OB\\test\\images'
# ======================================


imagesList = os.listdir(imagesPath)

def list_dir_in_folder(folderPath):
    resList = []
    folderList = os.listdir(folderPath)
    folderList = [os.path.join(folderPath, v) for v in folderList]
    for folder in folderList:
        if os.path.isdir(folder):
            resList.append(os.path.join(folderPath, folder))
    
    return resList

folderList = [obsidianVault]

def operate_in_folder(folderPath):
    print('='*64)
    print(f'cd {folderPath}')
    # 栈操作: 2.将对执行图片迁移操作的父文件夹中的子文件夹path加入栈中
    global folderList
    folderList.extend(list_dir_in_folder(folderPath))
    
    files = []
    for fileName in os.listdir(folderPath):
        if fileName[-3:] == '.md':
            filePath = os.path.join(folderPath, fileName)
            files.append(filePath)
    
    if not files:
        return
        
    for filePath in files:
        with open(filePath, 'r', encoding='utf-8') as f:
            content = f.read()
            pattern = r'!\[\[(.*?)]\]'       # 匹配 [[...]] 格式的内容
            imgs = re.findall(pattern, content)

        # 仅对含有图片的文档创建附件夹并移动相应的图片
        if imgs:
            fileName = os.path.basename(filePath)
            attPath = os.path.join(folderPath, accessoryPath, fileName[:-3])
            if not os.path.exists(attPath):
                os.makedirs(attPath)
            print(f'File: [{fileName}]. Attachments path: [{attPath}]. Total: [{len(imgs)}]')
            
            for img in tqdm(imgs):
                if img not in imagesList:
                    print(f'[WARNING]: {img} could not be found and will skip moving.')
                    continue
                srcPath = os.path.join(imagesPath, img)
                dstPath = os.path.join(attPath, img)
                # 如果已经存在,就不移动,针对md文档中的一张图片被多次引用的情况
                if not os.path.exists(dstPath):
                    shutil.move(srcPath, dstPath)
                
                imgLink = os.path.join(accessoryPath, fileName[:-3], img).replace('\\', '/').replace(' ', '%20')
                content = content.replace(f'![[{img}]]', f'![]({imgLink})')
            
            with open(filePath, 'w', encoding='utf-8') as f:
                f.write(content)
        
    print('-'*64)
    
while folderList:
    # 栈操作: 1.删除栈中的索引文件夹path
    operate_in_folder(folderList.pop())
print('\n\n[DONE]: Please check.')

根据自己的仓库位置将上述 config 中的设置成自己的就行。具体来说 obsidianVault 设置成你的顶层仓库位置就行, accessoryPath 是针对插件Custom Attachment location的配置,最后的 imagesPath 顾名思义就是所有图片的附件位置。

结果

在这里插入图片描述
运行过程如上图(会显示进入了哪些文件夹,以及在当前文件夹路径是否执行图片迁移操作以及迁移后的问题),更改的文件位置和文章内容文件所引如下图

在这里插入图片描述
在这里插入图片描述
执行完成后记得自己先大致审阅一遍,有小问题自己改改应该就行了。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值