有道云笔记迁移到Obsidian的方法(保留文件创建时间)

--- ## 目录 - 前言 - 有道云笔记导出 - 有道云笔记信息导出 - Python2和Python3共存 - 修改原代码 - 执行程序 - 一些可能遇到的问题 - 修改markdown文件的创建时间和修改时间 - 安装最新版powershell(版本7.1以上) - 修改powershell编码(代码页) - 编写脚本 - 使用脚本 - 一些可能遇到的问题 - 结语 ## 前言 前段时间突然发现,有道云笔记禁止导出笔记了。 以前好歹还是可以批量导出的,虽然只能导出成有道云的独有格式或者是pdf,但是好歹还是能导出的,结果现在是彻底禁止导出了。 去搜索了下有道云笔记导出,没想到真的有第三方的插件可以把有道云笔记里的笔记导出成markdown文件(下称md文件),再加上我最近正好接触到了一个免费笔记管理软件Obsidian,虽然这个软件没有云备份功能,但是他的文件都是本地存储,且是通用的markdown格式,也方便未来万一需要换软件的情况。(国内的大部分软件,就算能导出也都是独有格式,猜测是为了防止用户跑路吧) 思索之后,决定趁现在赶紧把有道云笔记里的东西迁移出来,防止之后彻底无法导出就完蛋了。 于是就有了这个教程。 这个教程主要分为两部分: 1. 导出有道云笔记里的内容为markdown文件 2. 修改导出的文件的创建时间和修改时间,与有道云笔记内匹配。 当然第二点只是针对于有强迫症的用户,对于一般用户来说,这点完全可以不用考虑。 那么总之,教程开始。 ## 有道云笔记导出 关于有道云笔记导出为md文件,其实github上已经有一个相当好的软件了:[youdaonote-pull][1] 这个软件的功能有: - 可将所有笔记(文件)按原格式下载到本地 - 由于「笔记」类型文件下载后默认为 Xml 格式,不是正常笔记内容,默认将其转换为 Markdown 格式 - 由于有道云笔记图床图片不能在有道云笔记外显示,默认将其下载到本地,或指定上传到 SM.MS 嗯……具体的使用方法在原网页上写的非常详细,我在这里就不搬了,大家自己去原网页看就行了。 我在这里就说两点: 1. 原网页里的第一步,如果没有git,也不想下载的话,可以不用按照原网页里说的使用git clone项目,只需要点击code内的Download ZIP按钮,即可下载全部文件,然后在本机上解压即可使用。 [![image](https://upload-images.jianshu.io/upload_images/14099399-e5dbb4245944cb22.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)](https://imgtu.com/i/HAcgOJ) 2. 如果在软件执行的过程中出现`转换为 Markdown 失败!请检查文件!`的错误,请自行检查文件名是否出错。(我自己是因为有道云的文件名里不知道为啥会包含两个换行符,所以报错了) 执行完这个程序,大家就能得到一个包含所有嵌套文件夹、笔记、图片文件(在根目录下的youdaonote-images文件夹内)、附件文件(在根目录下的youdaonote-attachments文件夹内)的文件夹了。 这个文件夹其实已经可以当成Obsidian的库被识别了,只需要在Obsidian内选择『打开库文件夹』,选择这个导出的根目录,就可以使用了。 如果没有强迫症的话,这个教程看到这里就结束了。但是,我有强迫症啊! 有道云笔记里,每一篇笔记都会记录他的创建时间和修改时间,但是使用[youdaonote-pull][1]导出的笔记,创建时间全部为导出的当天,这样就丢失了重要的时间信息。 于是才有了接下来的教程。 ## 有道云笔记信息导出 如果想要导出有道云笔记的信息(如时间等),就需要另一个软件了:[YoudaoNoteExport][2] 这个软件稍微有点年头了,2018年的,但是仍然可以使用。他的主要功能是导出有道云笔记,保存为JSON和DOCX/XML文件。DOCX/XML文件是笔记的内容,JSON文件是笔记的其它信息(包括标题、创建时间、修改时间等)。 我们正好需要这个软件导出的JSON文件,里面包含了文件的创建时间和修改时间。(这个软件导出DOCX有点问题,我用word无法打开,不过无所谓了,我们也不需要这个功能。) 这个软件导出的笔记默认文件名是笔记的id(一串数字和字母构成的字符串),我本来想把它改成以原笔记的名称作为文件名,但是遇到了一些问题,所以最后还是保留了id文件名,反正到时候遍历json文件的时候也不需要看这个文件名。 ### Python2和Python3共存 但是因为这个软件运行的环境是在Python2.7里的,而之前的[youdaonote-pull][1]是运行在Python3内的,这里就有一个问题就是需要Python2和Python3在同一个电脑内共存。 这个问题可以参考下面这两篇文章: [Windows10下python3和python2同时安装(一)安装python3和python2](https://blog.csdn.net/qiang12qiang12/article/details/53239734) [Windows10下python3和python2同时安装(二)python2.exe、python3.exe和pip2、pip3设置](https://blog.csdn.net/qiang12qiang12/article/details/53239866) 整体的做法按照这两篇文章内的设置就行,不过实际上,我自己只修改了python2和pip2。也就是命令python对应的是python3,而python2对应的就是python2,pip同理。(因为我准备做完这个导出就把python2卸载,然后保留python3的,所以我python3就没有做修改。) 总之不管怎么修改,现在的电脑内已经有了python2和python3两个版本了。不过在下载之前,还需要在python2内也安装requests库,如果大家按照之前两篇文章更改的话,那么安装的方式就是在命令提示符内输入: ``` pip2 install requests ``` 然后接下来就是下载[YoudaoNoteExport][2],和之前一样,只需要点击code里的Download ZIP下载所有文件,然后解压,得到一个名为YoudaoNoteExport-master的文件夹。 ### 修改原代码 **在使用之前,还需要对源码做一些修改。** 也不知道为啥,下载下来的源码如果直接使用,会有非常多的错误,这也是我之前导出的时候遇到的问题。所以要对原代码进行一些修改。 打开之前解压的YoudaoNoteExport-master文件夹,然后右键main.py文件,选择Edit with IDLE,或者打开方式记事本,然后参照下文修改程序即可。(建议安装一个[sublime编辑器](https://www.sublimetext.com/)) 这个程序的问题主要集中在函数`getFileRecursively`内,代码如下: ```py def getFileRecursively(self, id, saveDir, doc_type): data = { 'path': '/', 'dirOnly': 'false', 'f': 'false', 'cstk': self.cstk } url = 'https://note.youdao.com/yws/api/personal/file/%s?all=true&f=true&len=30&sort=1&isReverse=false&method=listPageByParentId&keyfrom=web&cstk=%s' % (id, self.cstk) lastId = None count = 0 total = 1 while count < total: if lastId == None: response = self.get(url) else: response = self.get(url + '&lastId=%s' % lastId) print('\n------') # print('getFileRecursively:' + response.content) jsonObj = json.loads(response.content) total = jsonObj['count'] for entry in jsonObj['entries']: fileEntry = entry['fileEntry'] id = fileEntry['id'] name = fileEntry['name'] print('%s' % (id)) # print('%s %s' % (id, name)) if fileEntry['dir']: subDir = saveDir + '/' + name try: os.lstat(subDir) except OSError: os.mkdir(subDir) self.getFileRecursively(id, subDir, doc_type) else: with open('%s/%s.json' % (saveDir, id), 'w') as fp: fp.write(json.dumps(entry,ensure_ascii=False).encode('utf-8')) if doc_type == 'xml': self.getNote(id, saveDir) else: # docx self.getNoteDocx(id, saveDir) count = count + 1 lastId = id ``` 需要修改的地方我都已经修改掉了,并且把原句注释了。 总共有两句需要修改: ##### 第一句 ``` # 原句: print('getFileRecursively:' + response.content) # 修改成print('\n------') ``` 修改这句的原因是因为,原程序这里输出了返回内容,但是猜测是因为返回内容过于巨大,实际输出之后会报错`IOError: [Errno 0] Error`。 ``` Traceback (most recent call last): File "main.py", line 137, in sess.getAll(saveDir, doc_type) File "main.py", line 118, in getAll self.getFileRecursively(rootId, saveDir, doc_type) File "main.py", line 91, in getFileRecursively print('getFileRecursively:' + response.content) IOError: [Errno 0] Error ``` 实测把这句直接注释掉,或者改成一些人畜无害的分隔线之类的就可以了。 ##### 第二句 ``` # 原句: print('%s %s' % (id, name)) # 修改成print('%s' % (id)) ``` 这句的问题是,最后输出了有道云笔记的文件名。 本来是没什么问题的,而且也能让人看得更清楚,但是笔记的文件名里如果有一些奇怪的Unicode字符(比如⊊),这里就会报错`UnicodeEncodeError`。 ``` Traceback (most recent call last): File "main.py", line 138, in sess.getAll(saveDir, doc_type) File "main.py", line 119, in getAll self.getFileRecursively(rootId, saveDir, doc_type) File "main.py", line 106, in getFileRecursively self.getFileRecursively(id, subDir, doc_type) File "main.py", line 106, in getFileRecursively self.getFileRecursively(id, subDir, doc_type) File "main.py", line 99, in getFileRecursively print('%s %s' % (id, name)) UnicodeEncodeError: 'gbk' codec can't encode character u'\u228a' in position 35: illegal multibyte sequence ``` 处理方法的话……我是直接把这段的name给删了,简单粗暴。虽然看不清文件名了但是好歹不会出问题了。大佬的话可以把这段稍微修改下…… ### 执行程序 修改完程序,保存之后,就可以执行了。 1. 首先打开命令提示符,将路径移动到之前解压的YoudaoNoteExport-master文件夹内,如: ```cmd D:\桌面\YoudaoNoteExport-master> ``` 2. 接着需要在YoudaoNoteExport-master文件夹内,新建一个notes文件夹。(这个文件夹名称可以随意,但是需要和下文的输入的路径统一) 3. 在命令提示符内输入如下命令: ```cmd D:\桌面\YoudaoNoteExport-master>python2 main.py <有道云的账号> <有道云的密码> ./notes xml ``` 接着等待程序自动执行完成即可。 ### 一些可能遇到的问题 - 报错:`IOError: [Errno 0] Error` 这个之前提到过,修改上文的第一句应该就行了。 - 报错:`UnicodeEncodeError: 'gbk' codec can't encode character u'\uxxxx' in position xxx: illegal multibyte sequence` 也是之前提到过的,修改上文的第二句应该就行了。 - 报错:`IOError: [Errno 22] invalid mode ('w') or filename: u'./notes/xxxx.json'` 这个错误是我之前想让程序以原笔记标题作为文件名,然后才遇到的问题。还是上文说的,不知道为啥我有个笔记标题里有两个换行符,所以导出的时候直接就报错了,后来我还是以id作为文件名就不报错了。 - 报错:`KeyError: 'fileEntry'` 这个错误会显示如下的信息: ```python getRoot:{"canTryAgain":false,"scope":"SECURITY","error":"207","message":"Message[AUTHENTICATION_FAILURE]: User token must be authenticated.","objectUser":null} Traceback (most recent call last): File "main.py", line 138, in sess.getAll(saveDir, doc_type) File "main.py", line 118, in getAll rootId = self.getRoot() File "main.py", line 53, in getRoot return jsonObj['fileEntry']['id'] KeyError: 'fileEntry' ``` 这个错误其实是因为登录次数太多,网页需要输入验证码了,没有验证码就相当于登不上去,所以返回的页面直接报错。 解决办法……就是再过一天再登录,应该就好了。 ## 修改markdown文件的创建时间和修改时间 经过了前两步,我们现在已经得到了两个文件夹,分别是由[youdaonote-pull][1]导出的装满markdown的文件夹,和[YoudaoNoteExport][2]导出的装满json文件的文件夹。 接下来要做的,就是将json文件中的创建时间、修改时间提取出来,再对md文件的属性进行更改。 这里我们选择windows10自带的powershell来完成这个工作,因为powershell对于文件基础属性的修改操作起来比较简单。 先分析一下[YoudaoNoteExport][2]导出的json文件:(实际导出的文件为仅有一行的json文件,为了看得清楚我已经格式化了) ``` { "otherProp": {}, "fileMeta": { "metaProps": { "WHOLE_FILE_TYPE": "NOS", "FILE_IDENTIFIER": "xxxx", "spaceused": "2213", "tp": "0", "st": "0" }, "sourceURL": "", "contentType": null, "author": "", "modifyTimeForSort": 1548934186, # 修改时间 "title": "xxxx.note", # 文件名 "sharedCount": 0, "externalDownload": [], "storeAsWholeFile": true, "fileSize": 2213, "resourceMime": null, "resourceName": null, "chunkList": null, "coopNoteVersion": 0, "resources": [], "createTimeForSort": 1547818247 # 创建时间 }, "fileEntry": { "domain": 0, "createProduct": null, "hasComment": false, "modifyTimeForSort": 1548934225, # 修改时间 "userId": "xxxxxx", "myKeepAuthorV2": "", "transactionTime": 1548934225, "myKeepAuthor": "", "id": "xxxx", "erased": false, "entryType": 0, "orgEditorType": 1, "version": 15899, "entryProps": { "orgEditorType": "1", "encrypted": "false", "modId": "xxxx", "bgImageId": "d-00", "PE_IMPORTED": "false" }, "createTimeForSort": 1547818258, # 创建时间 "parentId": "xxxx", "favorited": false, "noteSourceType": 0, "subTreeFileNum": 0, "tags": "", "deleted": false, "subTreeDirNum": 0, "myKeepV2": false, "noteType": "0", "fileSize": 2213, "modDeviceId": "xxxx", "financeNote": null, "noteTextSize": 0, "myKeep": false, "name": "xxxx.note", # 文件名 "checksum": "xxxx", "summary": "xxxxxxxxxxxx", "dirNum": 0, "rightOfControl": 0, "namePath": null, "transactionId": "xxxx", "publicShared": false, "fileNum": 0, "dir": false }, "ocrHitInfo": [] } ``` 可以看见`fileMeta`里的`title`字段的值,就是我们需要的文件名,而`createTimeForSort`和`modifyTimeForSort`就是文件的创建时间和修改时间。 注意:`fileEntry`里也有文件名(name字段),创建时间和修改时间,只需要选择一个来当做源数据即可,这里我们选择的是`fileMeta`里的。 因为两个软件导出的文件,相同笔记对应的路径都是相同的,所以整个powershell脚本的思路就是遍历所有的json,接着针对每一个json文件,提取出其中的文件名。 因为之前导出的笔记已经全部转换成了.md文件,所以这里就需要将文件名内的.note全部改为.md,其他后缀名不变。 而有了这个文件名之后,就可以到[youdaonote-pull][1]导出的文件夹里,找到对应的笔记文件。 然后提取`createTimeForSort`和`modifyTimeForSort`的值,这个值是一个时间戳,需要将它们转换成powershell可以直接读取的时间格式,接着修改对应的.md文件的创建时间和修改时间就行了。 ### 安装最新版powershell(版本7.1以上) 不过想要实现这个功能,还有一个问题,那就是时间戳的转换。虽然powershell里自带的`Get-Date`命令可以转换时间戳,但是这个功能需要在powershell 7.1以上才能使用,所以我们还需要安装一下powershell 7.1。 这个的安装比较简单,只需要在win10自带的应用商店里,搜索powershell,然后安装就行了。 这样安装的应该就是最新版的powershell了,目前2022年2月,安装的版本是7.2.1。(我win10自带的版本是5.1,不能转换时间戳) 注:查看powershell版本的方法:在powershell窗口内输入命令`$PSVersionTable.PSVersion`,然后得到的major、minor、patch三项的值合起来就是powershell的版本。 注2:如果windows没有应用商店,或者连不上应用商店,可以选择去GitHub上下载[PowerShell](https://github.com/PowerShell/PowerShell/releases),版本的话,可以根据自己的系统选择[PowerShell-7.3.0-preview.1-win-x86.msi(32位系统)](https://github.com/PowerShell/PowerShell/releases/download/v7.3.0-preview.1/PowerShell-7.3.0-preview.1-win-x86.msi)或者[PowerShell-7.3.0-preview.1-win-x64.msi(64位系统)](https://github.com/PowerShell/PowerShell/releases/download/v7.3.0-preview.1/PowerShell-7.3.0-preview.1-win-x64.msi) 安装完成之后,开始菜单里应该会有一个powershell程序,右键它,点击更多,然后以管理员身份运行,就可以打开powershell了。(其实也可以不以管理员身份运行,但是以管理员身份比较保险) [![image](https://upload-images.jianshu.io/upload_images/14099399-1b5bff43fb6cf638.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)](https://imgtu.com/i/HAcRm9) ### 修改powershell编码(代码页) 不过在使用powershell之前,还需要设置powershell的编码(代码页)。因为powershell默认使用的代码页是936,中文会显示乱码,然后就会导致json里有中文时执行程序报错`Cannot find path '<文件路径>' because it does not exist.`。 这个问题的解决方法可以参考这篇文章:[解决windowspowershell中文显示问号及乱码问题](https://blog.csdn.net/weixin_43426860/article/details/83348284) 注:想要查看当前代码页,可以右击powershell窗口的标题栏,然后点击属性里的『选项』选项卡,在下方可以看当前代码页的值。这里默认写的是936 (ANSI/OEM - 简体中文 GBK),需要将它改成65001 (UTF-8)。 ### 编写脚本 根据之前的思路,我写了一个powershell脚本。 ``` # 批量修改有道云笔记导出文件的创建时间和修改时间,使之与有道云笔记内部统一的小程序 # 因为YoudaoNoteExport导出的json不含文件夹的创建、修改时间 # 所以只修改了所有文件的创建时间、修改时间、访问时间,但是文件夹的没有修改 $jsonPath = "D:\Obsidian\3" # YoudaoNoteExport导出文件的根目录(json文件目录) $mdPath = "D:\Obsidian\4" # youdaonote-pull导出文件的根目录(md文件目录) # 自己使用时注意把 $pathJson 和 $mdPath 改成自己的路径 Get-Childitem -Path $jsonPath -Recurse -Include *.json | Foreach-Object { # 遍历所有导出的json $jsonContent = Get-Content $_ | ConvertFrom-Json # 转换json成powershell能识别的格式 $fileName = $jsonContent.fileMeta.title # 取出json里的title属性(文件名) if ($fileName -ne $null) { # 防止取不到title属性报错 if ($fileName.EndsWith(".note")) { # 搞这么复杂是防止文件名中出现".note",然后一用replace就全替换没了,所以只替换文件名最后的".note"(虽然是小概率事件……) $fileName = ($fileName.Remove($fileName.LastIndexOf(".note") , 5) + ".md") # 把json里以.note结尾的文件名改成.md } $mdFile = Get-Item ($_.DirectoryName.Replace($jsonPath , $mdPath) + "\" + $fileName) # 替换对应路径。DirectoryName取出的路径没有\,所以这边要补上 Write-Host ("正在修改:" + $_.BaseName + ",路径:" + $mdFile.FullName + "`n") # 最后加一个换行是因为不知道为啥经常会两行输出在一起…… if ($jsonContent.fileMeta.createTimeForSort -ne $null) { # 防止取不到createTimeForSort报错 $mdFile.CreationTime = Get-Date -UnixTimeSeconds $jsonContent.fileMeta.createTimeForSort # 修改创建时间 } if ($jsonContent.fileMeta.modifyTimeForSort -ne $null) { # 防止取不到modifyTimeForSort报错 $mdFile.LastWriteTime = Get-Date -UnixTimeSeconds $jsonContent.fileMeta.modifyTimeForSort # 修改修改时间 $mdFile.LastAccessTime = Get-Date -UnixTimeSeconds $jsonContent.fileMeta.modifyTimeForSort # 修改最后访问时间,和修改时间相同 } } else { Write-Host ("【警告】" + $_.Name + " 缺少title属性,无法处理。`n") } } ``` ### 使用脚本 首先需要注意一下,大家如果想要使用这个脚本,注意把最前面的`$pathJson`和`$mdPath`两个变量的值改成自己对应的路径(注意最后不要带\)。 然后使用脚本,有两种方式: 1. 将脚本代码修改之后,直接全选复制,然后在powershell界面里点击鼠标右键粘贴,之后回车执行代码。 2. 新建一个文本文档,将代码复制进文本文档,修改之后保存,接着把文件的后缀名改成.ps1,进入powershell界面执行。 不过第二种方式操作起来比较麻烦,还需要修改powershell执行脚本的权限,我就不多做介绍了,仅在此贴一篇文章供大家参考:[Powershell实现编写和运行脚本](https://www.jb51.net/article/72037.htm)。这篇文章里把powershell运行脚本遇到的一些问题和解决方法都写出来了,如果实在是需要使用脚本文件来执行代码,可以参考这篇文章。 ### 一些可能遇到的问题 - 报错:`ConvertFrom-Json : 传入的对象无效,应为“:”或“}”。` ```powershell ConvertFrom-Json : 传入的对象无效,应为“:”或“}”。 <这里是json内容> 所在位置 行:2 字符: 37 + $JsonContent = Get-Content $_ | ConvertFrom-Json + ~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand ``` 这个错误上文说过,是因为powershell使用的编码不支持中文造成的,解决方法可以参考这篇文章:[解决windowspowershell中文显示问号及乱码问题](https://blog.csdn.net/weixin_43426860/article/details/83348284) - 报错:`Cannot find path '<文件路径>' because it does not exist.` ```powershell Get-Item: Line | 10 | … $mdFile = Get-Item ($_.DirectoryName.Replace($jsonPath , $mdPath) + … | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Cannot find path '<文件路径>' because it does not exist. 正在修改:<文件名称>,路径: InvalidOperation: Line | 13 | $mdFile.CreationTime = Get-Date -UnixTimeSeconds $jsonCon … | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | The property 'CreationTime' cannot be found on this object. Verify that the property exists and can be set. InvalidOperation: Line | 17 | $mdFile.LastWriteTime = Get-Date -UnixTimeSeconds $jsonCo … | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | The property 'LastWriteTime' cannot be found on this object. Verify that the property exists and can be set. InvalidOperation: Line | 19 | $mdFile.LastAccessTime = Get-Date -UnixTimeSeconds $jsonC … | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | The property 'LastAccessTime' cannot be found on this object. Verify that the property exists and can be set. ``` 这个错误虽然错误信息这么长,核心问题其实是从[YoudaoNoteExport][2]导出的json文件里提取出文件名之后,在[youdaonote-pull][1]导出的相应文件夹内找不到对应的文件(一般为.md文件)。 错误产生的原因一般而言是json里的文件名和实际导出的文件名不相同造成的,比如文件名里有一些奇怪的字符,或者换行符(我就遇到过这两种情况),而转换成.md文件的时候这些奇怪的字符被删掉了,于是两边的文件名就不匹配了。 这时候只需要修改一下json内的`title`字段,删除掉那些有错误的文件名,或者直接将文件名改成和对应笔记相同即可。具体哪个json文件出错了,可以查看错误信息里的`正在修改:<文件名称>`里的文件名称找到对应的json文件。 不过有几点要注意: 1. 修改的时候要修改`fileMeta`下的`title`字段,因为原json文件里有两个地方都有文件名,一个是`fileMeta`下的`title`字段,另一个是`fileEntry`下的`name`字段,注意要修改前者。 2. 修改的软件可以使用记事本,但是建议使用[sublime编辑器](https://www.sublimetext.com/),如果json文件里有一些不显示的字符,这里面可以显示出来。 3. 因为原本的json文件是压缩成一行的,如果觉得寻找`title`字段比较困难,可以使用[JOSN格式化](https://www.bejson.com/)网站来使json更加的可读,也可以在网页上直接修改之后再复制到原json文件里保存。 ## 结语 那么到这里整个教程就算是结束了,如果操作没有问题的话,导出的笔记的创建时间应该已经和有道云内的创建时间同步了。 接下来只需要使用Obsidian打开这个文件夹作为库,就可以完美使用了。 不过最后要注意一点:如果想要移动这个文件夹的位置请直接使用剪切和粘贴,如果复制的话前面的工作就全部功亏一篑了。 最后感谢大家的阅读。 **Roi写于2022年2月2日。** **转载请注明出处。** [1]: https://github.com/DeppWang/youdaonote-pull [2]: https://github.com/wesley2012/YoudaoNoteExport

你可能感兴趣的:(有道云笔记迁移到Obsidian的方法(保留文件创建时间))