序
为了尽量讲解的通俗易懂,导致本文过于冗长,为了不浪费大家时间,简述下本文解决了什么问题:
- 针对资源文件的压缩处理、
- 针对资源文件压缩后扩展名(后缀)不一致的处理方法
- 提出一种批量替换思源文档的处理方法
本文响应「思源需要更好的文档」。并提供了完整的思源文档(思源导出的)。
对于自行编写帮助文档有意愿的朋友,可以在遵守开源精神的前提下自行取用。
【硬核】思源笔记同步空间压缩计划.sy.zip (10.12MB)
前言
在拜读 @qiancang 的 思源笔记同步空间拯救计划 之后,发现文中的情况并不适合我,
遂寻找一种可持续、可复现的操作手段来对资源文件夹的内容进行压缩规整,让我们开始吧。
如果您对思源笔记工作空间内的文件结构不太清楚,请查阅:
思源笔记文件系统介绍:数据快照与同步 - 知乎 (zhihu.com)
缓解数据焦虑,思源笔记文件存储介绍 - 链滴(ld246.com)
缓解数据焦虑,思源笔记文件存储介绍 2 - 链滴(ld246.com)
分析
想要进行空间压缩,第一步就是要知道目前空间占用情况,然后对相关文件进行分析,针对性的处理。
在这里推荐一款工具,名字叫:WizTree,并且个人免费使用。
下载地址:www.diskanalyzer.com/download
只需要点击即可下载。
软件中文切换方法:
软件使用方法:
如何导出/复制特定的文件类型方便进行二次处理
assets 资源文件默认存放着全部格式的文件,不方便进行操作,所以需要将特定的文件类型单独区分出来,方便二次操作。
方法一:按照类型排序,然后选择
使用排序功能后,文件就会按照类型进行排序,然后:
- 选中【你找到第一个视频】
- 按下 Shift 键,点击【你找到最后一个视频】
此时会选中【你找到第一个视频】和【你找到最后一个视频】之间的全部文件,
通过这种方法可以很方便的将特定类型的文件提取出来。
方法二:使用命令行窗口配合 xcopy 快速复制
按下 Windows + R 打开运行窗口,在打开处输入 cmd 然后回车,这个时候打开的就是命令行窗口了。
接着使用以下命令:
# 命令
xcopy "源文件路径" "目标文件夹路径" /s /i
# 例子
xcopy "C:\Users\xiaoqi\SiYuan\data\assets\*.png" "C:\Users\xiaoqi\Desktop\PNG" /s /i
解释一下这个命令:
-
xcopy
是 Windows 中的一个命令行工具,用于复制文件和目录。 -
"C:\Users\xiaoqi\SiYuan\data\assets\*.png"
是源文件路径。
这里指定了复制C:\Users\xiaoqi\SiYuan\data\assets
目录下所有扩展名为.png
的文件。
这里的*
你可以理解成【任意】。 -
"C:\Users\xiaoqi\Desktop\PNG"
是目标文件夹路径。
这里指定了将文件复制到C:\Users\xiaoqi\Desktop\PNG
目录下。 -
/s
选项表示复制包括子目录在内的所有文件。
如果源目录包含子目录,这个选项可以确保子目录中的文件也被复制。 -
/i
选项表示如果目标是一个目录,则创建目录。
如果目标文件夹C:\Users\xiaoqi\Desktop\PNG
不存在,该命令会自动创建它。
通过这种方法,在配合【任意】*
符号的使用(如视频:*.mp4
等),可以对多种格式快速的复制。
针对视频格式处理方法
如果你的视频占用高,那么可以尝试对视频进行压缩处理,具体操作方法如下:
方法一:使用 File Converter
这是一款开源的文件转换器,是属于 ffmpeg 的封装。
安装完成默认会在上下文菜单中增加一个菜单项。
下载地址:https://file-converter.io/
Github 地址:https://github.com/Tichau/FileConverter
使用方法:
!!使用的时候请注意!!
- 软件默认的压缩配置会将压缩完成的文件放置在同一文件夹
- 压缩完成的文件会自动重命名并且添加如:
(720p)
、(1080p)
等内容。
所以需要修改一下,不然不方便后期操作。
模板代码:
(p:m)压缩\(f) (p:m)保存文件夹\(f) ...
然后就可以全选压缩,等待....
完成后直接复制到 "C:\Users\xiaoqi\SiYuan\data\assets\"
覆盖它。
方法二:使用 FFmpeg
FFmpeg 用于处理视频、音频和其他多媒体文件及流的库和程序,广泛用于格式转码和基本编辑。
下载地址:www.gyan.dev/ffmpeg/builds
新建一个 bat 文件,将以下内容复制进去:
@echo off
setlocal
rem 设置 ffmpeg 的路径(例: D:\CommonTools\ffmpeg\bin\ffmpeg.exe)
set "ffmpeg_path=D:\CommonTools\ffmpeg\bin\ffmpeg.exe"
rem 待压缩视频文件夹(例: C:\Users\xiaoqi\Desktop\MP4)
set "input_folder=C:\Users\xiaoqi\Desktop\MP4"
rem 压缩后存放位置(例: C:\Users\xiaoqi\Desktop\MP4-ys)
set "output_folder=C:\Users\xiaoqi\Desktop\MP4-ys"
rem 创建输出文件夹(如果不存在)
if not exist "%output_folder%" (
mkdir "%output_folder%"
)
rem 遍历输入文件夹中的所有 MP4 文件
for %%f in ("%input_folder%\*.mp4") do (
echo 正在压缩 %%~nxf...
"%ffmpeg_path%" -n -stats -i "%%f" -c:v libx264 -preset medium -crf 21 -c:a aac -qscale:a 1.3 -vf "scale=1280:720,format=yuv420p" "%output_folder%\%%~nxf"
)
echo 压缩完成!
pause
注意修改:ffmpeg_path
、input_folder
、output_folder
,保存后双击运行,接着就是等待....
完成后请手动检查下文件夹内的文件数量是否一致,如不一致,请看本文 -> 文件不一致如何比对。
完成后直接复制到 "C:\Users\xiaoqi\SiYuan\data\assets\"
覆盖它。
针对图片格式处理方法
对于一些图片,也可以进行压缩,具体操作方法如下:
方法一:使用图压
这里我使用的是图压这一款软件,你也可以使用其他的图片压缩软件,操作步骤同理。
注:图压的项目源代码是申请开放制的,具体请看官网。
图压官网:https://tuya.xinxiao.tech/
目前官方网站已经无法正常浏览和下载软件了,但是你可以使用 Web 时光机功能,找到它,
请不要使用 xxx 下载站来下载。
注:archive 中文叫网页时光机,可以访问和浏览过去存档的网站。
软件很简洁,我推荐的方法设置方法是:
- 目标格式选择原格式
- 保存路径使用自定义位置
- 文件后缀清除
完成后请手动检查下文件夹内的文件数量是否一致,如不一致,请看本文 -> 文件不一致如何比对。
这样压缩好的图片就可以快速覆盖到 "C:\Users\xiaoqi\SiYuan\data\assets\"
方法二:使用压缩能力更加优秀的格式
图片格式可以使用更加优秀的格式来代替它,比如 WebP。
WebP 是由 Google 收购 On2 Technologies 后发展出来的图片格式,
根据业界给出的改造数据可知,改造 WebP 之后图片体积会降低很多:
具体可参照 WebP 体积测试链接。
注:浏览器支持程度和兼容性浏览:caniuse.com/?search=WebP,思源当然是支持的啦!
你可以使用上面的图压工具来压缩并且转换为 WebP 图片格式(目标格式选择 WebP) ,也可以使用以下方法:
@echo off
chcp 65001 >nul
:: 設置 cwebp.exe 的路徑(例:D:\CommonTools\cwebp.exe)
:: 详细介绍: https://rene78.github.io/batch-convert-to-webp
set "cwebp_path=D:\CommonTools\cwebp.exe"
:: 設置源文件夾路徑(例:C:\Users\xiaoqi\Desktop\PNG)
set "source_folder=C:\Users\xiaoqi\Desktop\PNG"
:: 設置目標文件夾(例:C:\Users\xiaoqi\Desktop\PNG1)
set "target_folder=%source_folder%\converted"
:: 確保目標文件夾存在
if not exist "%target_folder%" (
mkdir "%target_folder%"
)
:: 遍歷源文件夾中的所有支持的圖像文件
for %%f in ("%source_folder%\*.jpeg", "%source_folder%\*.jpg", "%source_folder%\*.png", "%source_folder%\*.bmp") do (
echo 正在處理文件:%%f
:: 提取文件名(不帶擴展名)
set "filename=%%~nf"
:: 執行轉換命令
"%cwebp_path%" -q 80 "%%f" -o "%target_folder%\%%~nf.webp"
)
echo 所有文件處理完成!
pause
这里主要不是介绍如何转换,而是介绍转换后的内容如何修改到思源。
其实答案很简单,即:修改笔记内容。
这里我的思路是直接在数据库里面将这部分内容查询出来,然后生成替换命令,直接运行命令替换,
如果大家有更加好的方法,欢迎在下面留言探讨,谢谢!
第一步:数据库找到相矣数据
这里我使用的是 HexHub,你也可以使用任意的工具,比如:
Sql 教程帖子定位:
思源 SQL 新人指南:SQL 语法 + Query + 模板
连接成功后先别急着查询,先来看看 assets 数据库表与字段分别代表什么意思。
此处参考:@shuoying 的思源笔记数据库表与字段一帖,感谢!
字段名 | 字段值示例 | 说明 |
---|---|---|
id |
20211127144458-uinrvpj |
引用 ID |
block_id |
20210512171633-u3iy2xx |
块 ID |
root_id |
20200915214115-42b8zma |
文档 ID |
box |
20210808180117-czj9bvb |
笔记本 ID |
docpath |
/20200812220555-lj3enxa/20210808180321-hbvl5c2/20200915214115-42b8zma.sy |
文档路径 |
path |
assets/siyuan-128-20210604092205-djd749a.png |
资源文件路径 |
name |
siyuan-128-20210604092205-djd749a.png |
资源文件名 |
title |
源于思考,饮水思源 |
资源标题 |
hash |
788c154262194a126b433b1055fbddcf5ada066e0d1f565a54e5550125675075 |
资源哈希值 |
需要修改笔记内容就需要找到这个资源对应是哪个文档,
而 path(资源文件路径)
、name(资源文件名)
这两个字段可以是哪个资源,
box(笔记本 ID)
、docpath(文档路径)
就可以确定是哪个笔记本及文件存放位置。
box: 20241224095229-yxbhu6o
docpath: /20241212102205-fwomcie/20240220165409-i5eml9m.sy
path: assets/image-20240319104536-66zo3wo.webp
name: image-20240319104536-66zo3wo.webp
通过这些数据可以看出:
一个 工作空间/data/20241224095229-yxbhu6o/20241212102205-fwomcie/20240220165409-i5eml9m.sy
的文档,
使用了 工作空间/data/assets/image-20240319104536-66zo3wo.webp
这个文件,
资源保存的文件名称叫 image-20240319104536-66zo3wo.webp
。
打开这个文档,使用搜索工具搜索 image-20240319104536-66zo3wo.webp
看看是否正确。
确定没问题后,接下来就可以通过 SQL 查询出全部内容来了,
这里主要是查询 png 格式的文件,也就是这样操作:
# 查询语句例子
## 查询 assets 表里面 path 字段全部为 .mp4 结尾的文件
SELECT * FROM assets WHERE path LIKE '%.mp4';
## 查询 assets 表里面 path 字段全部为 .png 结尾的文件
SELECT * FROM assets WHERE path LIKE '%.png';
...
第二步:构建替换命令
接下来就是想办法批量的将数据库查询出来 box(笔记本 ID)
、docpath(文档路径)
文档打开,
然后使用替换工具批量的替换里面的 path(资源文件路径)
、name(资源文件名)
资源扩展名。
比如:
一个 工作空间/data/20241224095229-yxbhu6o/20241212102205-fwomcie/20240220165409-i5eml9m.sy
的文档,
使用了 工作空间/data/assets/image-20240319104536-66zo3wo.png
这个文件,
资源保存的文件名称叫 image-20240319104536-66zo3wo.png
。
操作步骤:
我打开 工作空间/data/20241224095229-yxbhu6o/20241212102205-fwomcie/20240220165409-i5eml9m.sy
文档,
搜索 image-20240319104536-66zo3wo.png
这个资源文件名,替换成我前面压缩并且转换成 WebP 的文件名称,
也就是 image-20240319104536-66zo3wo.webp
,最后在保存。
使用方法:
替换操作我想到了 Linux
操作系统的 sed
命令,于是我尝试搜索一下是否能来 Windows
上使用 sed
这个命令工具。
Github 地址:https://github.com/mbuilov/sed-windows
下载链接:https://github.com/mbuilov/sed-windows/releases/tag/sed-4.9-x64-fixed
下载好之后其实就是一个很小的 exe
文件,我下载的是 sed-4.9-x64.exe 这个版本,使用方法如下:
常用例子:
# 打印文件 /etc/passwd 的第三行 # 指定地址定界 3 # command 命令设置为 p 即打印输出 # options 选项使用 -n 表示静默模式(多余的不显示) sed -n '3p' /etc/passwd # 打印文件 /etc/passwd 的第三行到第七行区间的内容 sed -n '3,7p' /etc/passwd # 使用正则表达式匹配: # 开始:/^root/ # 结束:/^sync/ # 打印开始和结束的区间的全部内容 sed -n '/^root/,/^sync/p' /etc/passwd # 在第一行前面指定添加字符串 # 1 指定第一行 # command 命令设置为 i:insert,增 # 666 是内容 # 第一行前面指定添加字符串 666 sed '1i666' /etc/passwd # 删除 /etc/passwd 文件中的第二行到第五行区间的内容 # 2,5 是区间 # command 命令设置为 d:delete 删 sed '2,5d' /etc/passwd # 查找并替换 # 将小写的 root 替换为大写的 ROOT,替换文件 /etc/passwd 的内容 # command 命令设置为 s:substitute 改 # 这里的 g 表示 global,意味着全局替换,简单来说就是替换全部 # 如果没有添加 g 如果查到有多条的情况下,默认替换第一条 sed 's/root/ROOT/' /etc/passwd sed 's/root/ROOT/g' /etc/passwd
接下来就是构建 sed
的替换命令了,注意看上面的常用例子,
options
选项都没有使用 -i
直接在原文件上进行操作的方式,下面就需要用到它。
思源工作空间路径
+ box(笔记本 ID)
+ docpath(文档路径)
就是需要替换的文档的绝对路径,
name
是搜索关键词,
对搜索关键词 name
修改后的结果就是替换内容。
# 对于 SQLite version 3.44.0 (2023-11-01) 之后的版本可以使用:
SELECT
CONCAT(
'D:/CommonTools/sed-4.9-x64.exe',
' -i "s/',
name,
'/',
REPLACE(name, '.png', '.webp'),
'/" "C:/Users/xiaoqi/SiYuan/data/',
box,
docpath,
'"'
) AS replace_command
FROM assets
WHERE name LIKE '%.png';
# 对于 SQLite version 3.44.0 之前的版本请使用:
SELECT
'D:/CommonTools/sed-4.9-x64.exe' ||
' -i "s/' ||
name ||
'/' ||
REPLACE(name, '.png', '.webp') ||
'/' ||
'"' ||
' ' ||
'"' ||
'C:/Users/xiaoqi/SiYuan/data/' ||
box ||
docpath ||
'"' AS replace_command
FROM assets
WHERE name LIKE '%.png';
如何查看版本?
使用
SELECT sqlite_source_id();
命令查看返回的日期。
这里需要注意的是:
-
D:/CommonTools/sed-4.9-x64.exe
需要替换成你的sed
位置
(当然你也可以将文件名称修改成sed.exe
并复制到C:\Windows
里面,这样就可以直接使用sed
代替它) -
C:/Users/xiaoqi/SiYuan/data/
思源工作空间路径需要添加data/
执行完毕后对查询结果导出,就获得了完整的操作命令啦~
第三步:执行替换操作
对于 Hexhub
软件来说,导出的 TXT
文件直接可以修改扩展名修改成 bat
或者 cmd
就可以直接双击运行了
HeidiSQL
则需要导出成 CSV
格式然后使用 Excel
打开复制 A1
列,复制到一个 bat
里面在运行。
或者你可以直接复制全部命令然后到 cmd
控制台粘贴回车自动运行....
这个时候工作空间的 "C:\Users\xiaoqi\SiYuan\data\assets\"
资源文件夹
既存在了原有的 png
又保留了压缩又转换的 WebP
这些文件可以使用思源的【设置】【资源】【未引用资源】处删除...
执行完毕后记得重建索引!
重建索引后数据库会刷新,可以通过这个机制来判断是否存在遗漏。
文件不一致如何比对
在处理时可能会存在压缩前后文件数量对不上的问题,如果不注意使用 sed
就进行替换的话,
就会出现大面积的资源文件丢失的情况(思源【设置】【资源】【资源文件丢失】)
所以需要在压缩/转换操作完成后对比压缩前和压缩后的文件数量,如果出现数量对不上,使用以下方法寻找文件:
方法一:使用 Excel
在 Windows
中,有个 dir
命令,用于列出当前文件夹的文件详细信息:
其中有个参数 /B
可以只显示全部文件的名称
通过这个命令在配合重定向输出 >
来使用,就可以快速实现指定文件夹快速名称导出。
为此制作了个简单的 bat 脚本:
@echo off
rem 生成当前文件夹的目录树并保存到 tree.txt 文件
dir /B > tree.txt
echo 目录树已保存到 tree.txt 文件中。
将上面的代码保存为一个 .bat
文件,然后直接复制到你要生成的文件夹内,双击运行。
当压缩前和压缩后的文件名称都有了,那就可以使用对比工具来对比下少了哪个文件了。
这里我直接使用 Excel,对比过程不在叙述。
方法二:使用 Python
直接使用 Python 来处理:
import os
import shutil
## 哪两个文件夹进行对比?
# 源文件夹
png_folder = r"C:\Users\xiaoqi\Desktop\PNG"
# 目标文件夹路径
webp_folder = r"C:\Users\xiaoqi\Desktop\converted"
## 对比完成后将缺失文件复制到此文件夹内
new_folder = r"C:\Users\xiaoqi\Desktop\missing_png"
# 创建新文件夹
if not os.path.exists(new_folder):
os.makedirs(new_folder)
# 获取 PNG 和 WEBP 文件列表
png_files = os.listdir(png_folder)
webp_files = os.listdir(webp_folder)
# 找出 PNG 文件在 WEBP 文件夹中缺失的文件
missing_png_files = [f for f in png_files if f.endswith(".png") and f.replace(".png", ".webp") not in webp_files]
# 将缺失的 PNG 文件复制到新文件夹
for f in missing_png_files:
src_path = os.path.join(png_folder, f)
dst_path = os.path.join(new_folder, f)
shutil.copy2(src_path, dst_path)
print(f"Copied {f} to {new_folder}")
print(f"Total {len(missing_png_files)} missing PNG files copied to {new_folder}")
本文参考内容
How to Concatenate Strings in SQLite
思源笔记文件系统介绍:数据快照与同步 - 知乎 (zhihu.com)
缓解数据焦虑,思源笔记文件存储介绍 - 链滴(ld246.com)
缓解数据焦虑,思源笔记文件存储介绍 2 - 链滴(ld246.com)
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于