给笔记批量添加 front matter
2025/4/17...大约 2 分钟
给笔记批量添加 front matter
什么是 front matter
markdown 文件中的front matter
指的是以yaml
格式在文件开头增加的元数据。front matter
需要用---
包裹
为什么要添加 front matter
文件的创建时间不准。基于 git 做同步的,比如在公司新建了几个文件,但是回家后并没有立即打开 obsidian 做同步,过了几天再拉下最新的文件,文件创建时间肯定变成当天了,而且是同时拉下来的,创建时间肯定一致了。 怎么解决呢?front matter
就能解决这个问题。
增量文档
使用Templater
插件制作front matter
模板
---
title: <% tp.file.title %>
category:
tag:
date: <% tp.date.now("YYYY-MM-DD") %>
create_date: <% tp.file.creation_date() %>
---
# <% tp.file.title %>
存量文档
用 python 脚本批量添加
# 添加依赖 处理 front matter的库
pip install python-frontmatter
脚本内容,添加了 title、category、tag、date、create_date ,可以根据自己喜好调整
# coding: utf-8
import os
import re
import time
import frontmatter
# 更新md文件的front matter:1.增加创建时间;2.提取tag
def update_front_matter(file):
with open(file, 'r', encoding='utf-8') as f:
post = frontmatter.loads(f.read())
is_write = False
if not post.metadata.get('title', None):
post['title'] = file.split('\\')[-1].split('.')[0]
if not is_write:
is_write = True
if not post.metadata.get('create_date', None):
timeArray = time.localtime((os.path.getctime(file)))
post['create_date'] = time.strftime("%Y-%m-%d %H:%M", timeArray)
if not is_write:
is_write = True
if not post.metadata.get('date', None):
timeArray = time.localtime((os.path.getctime(file)))
post['date'] = time.strftime("%Y-%m-%d", timeArray)
if not is_write:
is_write = True
ret_category = file.split('\\')[4].split('.')
if post.get("category", []) != set(ret_category):
post['category'] = ret_category
if not is_write:
is_write = True
# 将代码块内容去掉
temp_content = re.sub(r'```([\s\S]*?)```[\s]?','',post.content)
# 获取tag列表
tags = re.findall(r'\s#[\u4e00-\u9fa5a-zA-Z]+', temp_content, re.M|re.I)
ret_tags = list(set(map(lambda x: x.strip(), tags)))
print('tags in content: ', ret_tags)
print('tags in front matter: ', post.get("tags", []))
if len(ret_tags) == 0:
pass
elif post.get("tags", []) != set(ret_tags):
post['tags'] = ret_tags
if not is_write:
is_write = True
if is_write:
with open(file, 'w', encoding='utf-8') as f:
f.write(frontmatter.dumps(post))
# 递归获取提供目录下所有文件
def list_all_files(root_path, ignore_dirs=[]):
files = []
default_dirs = [".git", ".obsidian", ".config"]
ignore_dirs.extend(default_dirs)
for parent, dirs, filenames in os.walk(root_path):
dirs[:] = [d for d in dirs if not d in ignore_dirs]
filenames = [f for f in filenames if not f[0] == '.']
for file in filenames:
if file.endswith(".md"):
files.append(os.path.join(parent, file))
return files
if __name__ == "__main__":
# file_path = 'D:/life-doc/docs/view/algorithm/readme.md'
# update_front_matter(file_path)
ignore_dirs = [".obsidian"]
files = list_all_files('D:\\life-doc\\docs\\view', ignore_dirs=ignore_dirs)
print("current dir: ", os.path.dirname(os.path.abspath(__file__)))
for file in files:
print("---------------------------------------------------------------")
print('current file: ', file)
update_front_matter(file)
time.sleep(1)