12000条笔记从印象笔记到Obsidian
2022 年年初,我曾经评估了印象笔记的优缺点,暂时留在了印象笔记。然而,印象笔记的超级笔记上线三年之后,依旧没有解决最最基本的、每天都要碰到的编辑器 “11 号字体大小” 问题——默认字体大小是11号,但编辑器快捷菜单中却只有偶数号字体。虽然我多次提交问题,并在 2022 年想办法申请了印象大使,混进印象大使的沟通群,能够直接联系到“印小象”,竟然这解决问题没有任何帮助。这最终让我失去了耐心。
另外,最新关于 Evernote 的消息是,在被意大利 Bending Spoons 收购一年之后,其开发全部转移到欧洲,美国硅谷的大部分团队将被解雇。
我的目标是将70个笔记本、12000条笔记、15GB数据,用最快捷的方案迁移到 Obsidian,同时保留笔记内链。
目标为什么是 Obsidian 而不是其他?
为了尽可能保留、还原笔记内链。
印象笔记是可以做笔记之间链接的——在卡片笔记法中,笔记互链是经常采用的整理手段。
2013 年,我曾经从 Evernote 迁移到印象笔记,期间就已经大量的损失了笔记的内部链接——所有内链都会跳转到原有服务器。Evernote 早期设计中并没有考虑到服务器切换,即便是 Evernote -> 印象笔记也无法正确处理内部链接。
具体拆解一下,内部链接大概是这样的:
evernote:///view/2080447/s13/21dd4785-5b73-412f-b226-78cb9513z474/2228c785-5b73-412f-b226-78198313a474/
我们观察一个 .enx 导出文件就可以看到,内部用的是 <a href=”evernote…”> 这样的标签:

究其原因,Evernote 的导出文件为 xml 格式,内部链接将转换为 evernote:/// 开头的专有链接,这些链接是不会随着软件转换而自动转换的,而是点击之后跳转回印象笔记APP。因为印象笔记的 enex 导出格式并不包含独立的 ID 标记,也就很难回溯到每一个笔记的位置。这个问题并不是导入软件的问题,虽然并不是没有办法,但几乎没有第三方笔记软件针对性的来解决。
因此,evernote: 这样的内部链接对我们新的笔记软件是没有任何意义的,必须想办法找回笔记之间的关联。
不解决这个问题,笔记间的相互关系就始终锁定在了印象笔记的框架里面,无论你把笔记转移到那个平台。10年以前,从 Evernote 到印象笔记存在这个问题。10 年以后,从印象笔记转移出来依旧面临这样一个问题。
当然,这个问题 Joplin、Logseq、OneNote 等诸多笔记软件也或多或少的存在,在处理内部链接的时候,都会采用一些自定义的唯一编码。
这个时候就轮到 Obsidian 出场了。
Obsidian 有一个独有的设计,Wiki 格式的链接。不需要指定链接,只要知道标题,就能跳转到对应的笔记。
由于大部分内链是直接使用原有笔记标题的,只要笔记标题没有改动,将其转换为 Wiki 格式的链接,如 [[这是一条测试笔记]]
,Obsidian 会自动匹配笔记,这在一定程度上缓解了内部链接丢失的问题,挽救我们转移过程中七零八落的笔记卡片。
并且,后面提到的 Yarle 转换工具,会尝试通过解析 evernote 链接-标题,来纠正链接。虽然有一些 bug,但这也是唯一我见到的尝试这么做的工具。
所以,总体思路就是:第一印象笔记导出 enex 文件,第二将 enex 文件转换为 markdown 格式文件,第三处理 md 文件中的内部链接,第四把 md 文件合并到 Obsidian 库中。
一、将印象笔记的数据导出为 enex 文件
印象笔记可以按照笔记本导出。
2022 年下半年发布的 7.0 以后的版本已经关闭了通用的 . enex 导出,所以需要从网上找一个 6.22.54.4163 这样的版本。6.0 的数据库和 7.0 之后的版本是完全兼容的,直接卸载新版,安装旧版就可以。
印象笔记历史老版本下载 丨『白云居』资源分享 (baiyunju.cc)

使用第三方 Evernote-backup 工具
印象笔记只能一个一个的笔记本导出。
如果你的笔记本特别多的话——比如我有70个笔记本,就需要一个更加自动化的工具,比如 Evernote-backup。
evernote-backup: Backup & export all Evernote notes and notebooks 可以从 github 上下载。
这个命令行工具可以从后台登录服务器,重新同步一份数据,然后一次性的导出所有的笔记本。缺点是不能使用印象笔记本地已经下载的数据,需要重新下载一份。
使用这个软件只需要用到三个命令行,导出的 enex 会整齐的码放在对应的导出目录中。
$ evernote-backup init-db --backend china
$ evernote-backup sync
$ evernote-backup export output_dir/
二、通过 Joplin 将 enex 转换为 md
随后我们就得到了一堆 enex 文件,有两条路径转换为 md 文件,Joplin 或者 Yarle,都有图形化界面。
Joplin (joplinapp.org) 本身也是一个笔记软件,可以从官网下载。
从 Joplin 的菜单中选择导入,由于目标是 Obsidian,可以选择直接导入成 Markdown 文件,而不是 HTML。导入 HTML 似乎会丢失一部分附件,Joplin 的 HTML 编辑器并不是特别好用,因此即使是停留在 Joplin,也建议导入成 Markdown 格式。

Joplin 会把印象笔记的导出格式都解析一遍,如果原有格式比较复杂的话,会丢失一些信息。但总体还好。
导入之后就可以导出了,选择“Markdown + 文章前言”这种格式,文章前言就是 front-matter,印象笔记的标签等信息会写在这一部分,如果不选择这个格式的话,tag 就丢失了。
使用 VS Code 处理内链
Joplin 没有办法处理 evernote 内链。我们需要对导出部分的链接进行手动处理,改成 Wiki 格式。
Visual Studio Code – Code Editing. Redefined 可以从官方网站下载,这是我能够想到的图形化的文本文件批量替换的工具,能够和 Obsidian 很好的配合工作,当然其他的 regex 工具应该也可以。
使用 VS Code 打开 md 所在的目录,进行整个目录进行查找替换就搞定了。

搜索下述正则表达式:
\[([^\[\]]+)\]\(evernote:[^)]+\)
替换为
[[$1]]
这种方式当然比较粗暴,毕竟转换成 md 文件的时候,很多文件名是进行了处理的,比如 | 等符号都需要进行替换,如果只是简单的把链接名字改过来,会有很多的链接失效,在 Obsidian 使用的过程中一个一个手工再调整过来。
此外,印象笔记APP偶然会生成 https://app.yinxiang.com 或者 http://www.yinxiang.com 开头的内链,需要进行类似的处理。
三、使用 Yarle 转换 enex 文件(并处理内链)
Joplin 只能一个一个的导入和导出。
Yarle – The ultimate converter of Evernote notes to Markdown 是一个 enex 转换 md 的工具,可以比较好的处理上述链接转换的问题,特别是能够比较正确的处理跨笔记本的内链。同时 Yarle 也支持批量的进行转换,对于有大量的笔记的朋友们更为友好。
Yarle 官网上提供的是图形界面的版本,可以选择需要转换的文件(支持同时转换多个)和进行简单的配置。

其中的一些有关于 Obisidian 的配置,特别要注意的是附件的存放方式,有三种:每个笔记单独存放,每个笔记本单独存放(Store attachments in notebook-level),所有笔记本放在一起(Store all attachments in one folder)。可以根据笔记的数量和复杂度来选择。
Omit links' display name: yes 用最简短的链接方式
Convert webclips: yes 网页剪辑也转换
Store attachments in notebook-level: yes 把同一个 Notebook 的附件放在一起
Add # to tag: no 标签中不要 # 但似乎不起作用
输出模板配置,默认模板的 YAML 部分写法是有错误的,可以参考 Joplin 的输出改成简单的版本:
---
{created-at-block}created: {created-at}{end-created-at-block}
{updated-at-block}updated: {updated-at}{end-updated-at-block}
{source-url-block}source: {source-url}{end-source-url-block}
{tags-array-block}tags: {tags-array}{end-tags-array-block}
---
{content-block}{content}{end-content-block}
Yarle 的使用说明中建议,在印象笔记导出笔记本的时候,对每一个笔记本用生成目录功能,生成一个目录。因为目录是包含一份完整的链接的,也就把所有的笔记 ID 带了出来,这样 Yarle 就可以用这样一份目录,来矫正导入时候的笔记相互关系,提高准确度。我试了试,有帮助,但是也有 bug。

经测试,Yarle 工具将 enex 转换为 markdown 的过程记录在 .log 文件中,在 Windows 平台下可以开一个单独窗口来看 .log:
Get-Content 'C:\Users\用户名\AppData\Roaming\yarle-evernote-to-md\conversion.log' -encoding UTF8 -wait
但对于 evernote:/// 内链替换处理,Yarle 却放在了控制台中。一旦要转换的笔记比较多,控制台一直在后台滚动,图形界面就会卡死。因此,如果笔记比较多的话(大于1000条),强烈推荐使用命令行。命令行需要在本地建立 config.json 配置文件。在使用图形界面的时候,在转换日志前面能找到自动配置生成的配置文件,没问题的话直接复制出来保存为 config.json 就好了。
npx -p yarle-evernote-to-md@latest yarle --configFile <path_to_your_file e.g. ./config.json>
内链的查找替换是一个漫长的过程——时间根据笔记的数量呈指数般的增加,5000 条笔记的查找替换需要好几个小时。
2023-07-13 Obisidian 上架了 Importer 插件,可以直接导入 enex 文件。这个插件是基于 Yarle 的,一次只能导入一个 enex 文件,且无法进行配置。所以对于大量导入,还是需要直接使用 Yarle。
四、将 md 导入到 Obsidian
最后一步是最简单的。Yarle 默认导出的文件的格式是每个笔记本一个目录:
\notes
\笔记本 1
\_resources
\目录 1.md
\笔记 1.md
\笔记本 2
\_resources
\目录 2.md
\笔记 2.md
把整个目录直接剪切到 Obsidian 库里面去就好了。Obsidian会对新增加的文件建立索引,然后你就得到了一个合并之后的库。

由于 HTML 到 md 的转换,除了 | 这样的笔记标题生成的 md 文件会被自动更名,还有有很多的细节问题,比如 # 识别成 tag,tag 中原有的 @ 等符号失效等。对于一个大的笔记库来说,还有很多整理的工作需要做。不过我们终于得到了一个可以用的大型迁移方案。
2023-07-28 张玉新老师留言问到了导入之后 Obsidian 的性能问题。在我的 Windows 11, 11gen i5, 16GB, SSD 的硬件下面,1.3万个md文件,61万行md代码,冷启动大概需要22秒,加载全文搜索大概需要54秒,单次全文搜索大概需要10秒。初次完成双链索引会用掉一两分钟,之后插入双链等编辑功能就是瞬时的了,偶然会有笔记读取卡顿的情况。