Skip to content

批量操作技巧

随着笔记数量增加,单条操作效率低下。掌握批量操作技巧,可以大幅提升笔记管理效率。

批量重命名

内置重命名

文件重命名:

  1. 在文件列表中右键点击文件
  2. 选择「重命名」
  3. 输入新名称
  4. 自动更新所有链接

批量重命名:

  1. 选择多个文件(Ctrl+点击
  2. 右键选择「重命名」
  3. 使用模板批量修改

使用插件重命名

File Cleaner 插件:

yaml
功能:
  - 删除空文件
  - 删除未使用的附件
  - 批量重命名

Templater 脚本重命名:

javascript
<%*
// 批量重命名文件夹下的文件
const folder = app.vault.getAbstractFileByPath("笔记文件夹");
const files = app.vault.getMarkdownFiles()
  .filter(f => f.path.startsWith("笔记文件夹/"));

for (const file of files) {
  const newName = "前缀_" + file.name;
  await app.fileManager.renameFile(file, file.parent.path + "/" + newName);
}
%>

正则表达式重命名

使用「Rename Note」插件:

yaml
规则示例:
  原名: (\d{4}-\d{2}-\d{2})-(.*)
  新名: 日记/$1/$2
  
  原名: (.*)\.md
  新名: 归档/$1

批量移动

文件夹操作

拖拽移动:

  1. 选择多个文件
  2. 拖拽到目标文件夹
  3. 确认移动操作

剪切粘贴:

  1. 选择文件,Ctrl+X
  2. 打开目标文件夹
  3. Ctrl+V 粘贴

按条件移动

使用 Dataview 查询后移动:

dataview
LIST
FROM ""
WHERE file.mtime < date(today) - dur(90 days)

使用脚本批量移动:

javascript
<%*
// 移动 90 天未修改的文件到归档
const archivePath = "归档";
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - 90);

const files = app.vault.getMarkdownFiles();
for (const file of files) {
  if (file.stat.mtime < cutoffDate.getTime()) {
    const newPath = archivePath + "/" + file.name;
    await app.fileManager.renameFile(file, newPath);
  }
}
%>

批量修改内容

查找替换

内置查找替换:

  1. Ctrl+H 打开查找替换
  2. 输入查找内容
  3. 输入替换内容
  4. 点击「全部替换」

多文件查找替换:

  1. Ctrl+Shift+H 全局查找替换
  2. 设置搜索范围
  3. 执行批量替换

使用正则表达式

yaml
常用正则:
  删除空行: ^\s*$ → (空)
  统一日期格式: (\d{4})/(\d{2})/(\d{2}) → $1-$2-$3
  添加标签: ^# (.*) → # $1\n#标签名

批量添加 Frontmatter

使用 Templater:

javascript
<%*
// 为所有笔记添加属性
const files = app.vault.getMarkdownFiles();
for (const file of files) {
  const content = await app.vault.read(file);
  
  // 检查是否已有 frontmatter
  if (!content.startsWith("---")) {
    const frontmatter = `---
created: ${file.stat.ctime}
modified: ${file.stat.mtime}
---\n\n`;
    await app.vault.modify(file, frontmatter + content);
  }
}
%>

批量添加标签

使用搜索替换

查找: ^# (.*)
替换: # $1\n#新标签

使用插件

Tag Wrangler 插件功能:

  • 批量重命名标签
  • 合并标签
  • 删除标签

Templater 脚本

javascript
<%*
// 为特定文件夹的文件添加标签
const folder = "项目";
const files = app.vault.getMarkdownFiles()
  .filter(f => f.path.startsWith(folder));

for (const file of files) {
  const content = await app.vault.read(file);
  if (!content.includes("#项目")) {
    await app.vault.append(file, "\n\n#项目");
  }
}
%>

批量创建笔记

从模板创建

使用 Templater:

javascript
<%*
// 批量创建日记
const startDate = new Date("2024-01-01");
const endDate = new Date("2024-12-31");

for (let d = startDate; d <= endDate; d.setDate(d.getDate() + 1)) {
  const dateStr = d.toISOString().split('T')[0];
  const fileName = `日记/${dateStr}.md`;
  
  if (!await app.vault.adapter.exists(fileName)) {
    await app.vault.create(fileName, `# ${dateStr}\n\n`);
  }
}
%>

从 CSV 创建

使用 Dataview:

dataviewjs
// 从 CSV 读取数据创建笔记
const csv = await app.vault.adapter.read("data.csv");
const rows = csv.split("\n").slice(1); // 跳过标题行

for (const row of rows) {
  const [title, content] = row.split(",");
  const fileName = `笔记/${title}.md`;
  await app.vault.create(fileName, `# ${title}\n\n${content}`);
}

批量删除

删除空文件

使用 File Cleaner 插件:

yaml
配置:
  删除空文件: true
  删除空文件夹: true
  保留特定文件: false

删除未使用的附件

查找未使用的附件:

dataview
LIST
FROM "附件"
WHERE !file.outlinks

Templater 清理脚本:

javascript
<%*
// 删除未被引用的图片
const images = app.vault.getFiles()
  .filter(f => f.extension.match(/png|jpg|jpeg|gif/));

for (const image of images) {
  const backlinks = app.metadataCache.getBacklinksForFile(image);
  if (backlinks.size === 0) {
    await app.vault.trash(image);
    console.log(`已删除: ${image.path}`);
  }
}
%>

批量导出

导出为 PDF

使用命令:

  1. 选择要导出的文件
  2. 右键 → 导出为 PDF
  3. 选择输出位置

导出为 Markdown

保留链接关系:

javascript
<%*
// 导出笔记及关联笔记
const startFile = app.workspace.getActiveFile();
const exported = new Set();

async function exportWithLinks(file, depth = 0) {
  if (exported.has(file.path) || depth > 2) return;
  exported.add(file.path);
  
  const content = await app.vault.read(file);
  const exportPath = `导出/${file.name}`;
  await app.vault.adapter.write(exportPath, content);
  
  // 获取链接的文件
  const links = app.metadataCache.getFileCache(file)?.links || [];
  for (const link of links) {
    const targetFile = app.metadataCache.getFirstLinkpathDest(link.link, file.path);
    if (targetFile) {
      await exportWithLinks(targetFile, depth + 1);
    }
  }
}

await exportWithLinks(startFile);
%>

批量格式化

统一格式

使用 Linter 插件:

yaml
规则:
  - 标题格式: 统一标题层级
  - 列表格式: 统一列表符号
  - 空行: 统一空行数量
  - 标签格式: 统一标签位置

批量调整标题

Templater 脚本:

javascript
<%*
// 将所有标题提升一级
const file = app.workspace.getActiveFile();
let content = await app.vault.read(file);

content = content.replace(/^#{1,6} /gm, match => {
  const level = match.length - 1;
  return level > 1 ? '#'.repeat(level - 1) + ' ' : match;
});

await app.vault.modify(file, content);
%>

批量操作工具对比

工具适用场景学习曲线
内置搜索替换简单文本替换
正则表达式复杂模式匹配
Templater自定义脚本
Dataview数据查询操作
专用插件特定功能

安全操作建议

操作前备份

yaml
备份方式:
  1. 使用 [文件恢复核心插件](/basics/file-recovery)
  2. Git 版本控制
  3. 手动复制库文件夹

小批量测试

  1. 先在少量文件上测试
  2. 确认结果正确
  3. 再执行批量操作

使用撤销

  • Ctrl+Z 撤销最近操作
  • 注意:某些批量操作无法撤销

实用脚本集合

批量添加创建日期

javascript
<%*
const files = app.vault.getMarkdownFiles();
for (const file of files) {
  const content = await app.vault.read(file);
  if (!content.includes("created:")) {
    const frontmatter = `---\ncreated: ${new Date(file.stat.ctime).toISOString().split('T')[0]}\n---\n\n`;
    await app.vault.modify(file, frontmatter + content);
  }
}
%>

批量整理附件

javascript
<%*
// 按年份整理附件
const files = app.vault.getFiles()
  .filter(f => f.extension.match(/png|jpg|jpeg|gif|pdf/));

for (const file of files) {
  const year = new Date(file.stat.ctime).getFullYear();
  const newPath = `附件/${year}/${file.name}`;
  
  if (file.path !== newPath) {
    await app.fileManager.renameFile(file, newPath);
  }
}
%>

批量生成索引

javascript
<%*
// 为每个文件夹生成索引
const folders = app.vault.getAllFolders();

for (const folder of folders) {
  const files = app.vault.getMarkdownFiles()
    .filter(f => f.parent.path === folder.path);
  
  if (files.length > 0) {
    let content = `# ${folder.name || "根目录"} 索引\n\n`;
    
    for (const file of files) {
      content += `- [[${file.basename}]]\n`;
    }
    
    const indexPath = folder.path + "/索引.md";
    await app.vault.adapter.write(indexPath, content);
  }
}
%>

提示

批量操作前务必备份!复杂的批量操作建议先用小规模数据测试。

注意

某些批量操作(如删除)可能无法撤销,请谨慎操作。

最后更新:2026年2月28日编辑此页反馈问题