上次用思源还是上次,大概在做终身会员活动的时候有过一个月体验,因为当时内核崩溃次数比较多,也有点卡(尤其是图谱)所以印象中思源的体验并不好。
这段时间跟别人推荐 Obsidian 和 Anytype 时被反向推荐了,于是再次安装试试看。
三步走(每一步都要做好备份)
- 正则替换图片链接
- 将创建时间替换为思源文件的 UID(这一步很慢
- 替换块 ID(可选,好像有点问题,但这一步挺快的,可以试试)
简单体验后认为思源的进步确实蛮大的,丝滑,稳定,决定从 Obsidian 换到思源。
当然,换笔记软件的第一步是尝试把整个 Ob 库迁移过去。
这里有几个点要注意:
-
虽然思源支持 Markdown 文件夹导入,但是思源对于链接的格式有一定要求。这个地方我试了好久,才在论坛上看见答案。
- 附件的格式需要是 md 链接
![]()
- 内链的格式需要是 wiki 链接
[[]]
- 附件的格式需要是 md 链接
-
导入到思源的文件,创建日期根据文件的 UID 来判断,但 UID 是根据在思源中创建文件的时间来生成。
-
无序列表里的内链不能被转换
下面是解决前两步的方法
尝试前,建议先备份 OB 库文件,新开一个思源工作空间。
仅仅抛砖引玉,如果各位大佬有更好的办法,那你们就用更好的办法!
第一步 将附件的链接改为 md 链接
进行全局搜索替换,该方案来自 Obsidian 论坛,我增加了一些格式。
可以使用 vscode 等软件打开 ob 库文件夹(最好备份一下)使用 linter 插件应该也行,我没试。
搜索:
!(\[\]\(<*)(.*?)([.])(png|jpg|jpeg|bmp|gif|tiff|canvas|svg|webp|pdf|epub|gif|excalidraw|excalidraw.md|mp4|JPG|PNG|anyotherimagetype)(.*?)(?:\|.*?)*(?:#.*?)*\)
替换:
![](/$2$3$4)
第二步 更改思源中文件的 UID,以达到思源创建日期与 ob 定义的创建日期相同
效果:
步骤:
-
在 Obsidian 中使用 linter 等插件在 metadata 中添加
created
,我的格式是YYYY/MM/DD HH:mm:ss Z
-
在思源中导入 markdown 文件夹,复制文件夹路径,然后关闭思源(最好关闭)
-
复制 python 代码(引导 GPT 生成的),将倒数第二行的文件夹路径替换为导入笔记的路径,然后运行。
import os import re from datetime import datetime def extract_original_date(filename): match = re.match(r'^(\d{14})-', filename) return match.group(1) if match else None def extract_replace_date(content): match = re.search(r'created: (\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}) \+\d{2}:\d{2}', content) if match: created_date = match.group(1) dt_obj = datetime.strptime(created_date, '%Y/%m/%d %H:%M:%S') return dt_obj.strftime('%Y%m%d%H%M%S') def generate_new_uid(original_uid, replace_date): return original_uid.replace(extract_original_date(original_uid), replace_date, 1) def process_folder(folder_path): for root, _, files in os.walk(folder_path): for filename in files: if filename.endswith('.sy'): file_path = os.path.join(root, filename) with open(file_path, 'rb') as f: try: content = f.read().decode('utf-8') except UnicodeDecodeError: print(f"Error decoding file: {file_path}") continue replace_date = extract_replace_date(content) if replace_date: original_uid = os.path.splitext(filename)[0] new_uid = generate_new_uid(original_uid, replace_date) new_filename = new_uid + '.sy' new_content = content.replace(original_uid, new_uid) new_file_path = os.path.join(root, new_filename) os.rename(file_path, new_file_path) with open(new_file_path, 'w', encoding='utf-8') as f: f.write(new_content) # Replace original UID with new UID in other files for root2, _, files2 in os.walk(folder_path): for filename2 in files2: if filename2.endswith('.sy'): file_path2 = os.path.join(root2, filename2) with open(file_path2, 'rb') as f2: try: content2 = f2.read().decode('utf-8') except UnicodeDecodeError: print(f"Error decoding file: {file_path2}") continue new_content2 = content2.replace(original_uid, new_uid) with open(file_path2, 'w', encoding='utf-8') as f2: f2.write(new_content2) # 调用示例 folder_path = r'D:\笔记\SiyuanObsidian导入\data\20230816005055-be9q8kj\20230816025046-f1kqm5h' print(f"Processing folder: {folder_path}") process_folder(folder_path) print("Processing complete.")
等待转换完成,这个代码比较慢,它的原理是用 created 中的日期替换旧 UID 的日期形成新的 UID,然后全局搜索旧 UID 替换为新 UID。耐心等等。
替换块 ID
import os
import re
def collect_new_uids(folder_path):
new_uids = []
for root, _, files in os.walk(folder_path):
for filename in files:
if filename.endswith('.sy'):
new_uid = os.path.splitext(filename)[0]
new_uids.append(new_uid)
return new_uids
def process_folder_with_global_new_uids(folder_path, new_uids):
for root, _, files in os.walk(folder_path):
for filename in files:
if filename.endswith('.sy'):
file_path = os.path.join(root, filename)
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
file_new_uid = os.path.splitext(filename)[0]
block_ids = re.findall(r'\d{14}-[a-zA-Z0-9]{7}', content)
for block_id in block_ids:
if block_id not in new_uids and "Data\":\"assets/" not in content:
new_block_id = file_new_uid[:12] + block_id[12:]
content = content.replace(block_id, new_block_id)
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
# 调用示例
folder_path = r'D:\笔记\SiyuanObsidian导入\data\20230816005055-be9q8kj\20230816025046-f1kqm5h'
new_uids = collect_new_uids(folder_path)
process_folder_with_global_new_uids(folder_path, new_uids)
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于