a2d-diary:Python命令行日记工具,实现Markdown存储与自动化工作流

发布时间:2026/10/10 11:48:23
a2d-diary:Python命令行日记工具,实现Markdown存储与自动化工作流 1. 先搞清楚a2d-diary到底解决什么问题市面上的笔记软件和日记工具我基本都折腾过一遍要么太重一套 Electron 应用吃我几百兆内存要么太封闭数据锁在私有格式里想导出比搬家还难。而 Python 生态里的 a2d-diary 属于另一类东西一个跑在终端里的纯文本日记工具包。它不提供花哨的图形界面而是把“记日记”这件事拆成了一组可编程的语法命令和参数接口让日记变成一份带时间索引、可检索、可渲染成 Markdown 的本地文件集合。a2d-diary 解决的核心痛点有三个。第一随手记打开终端敲一行命令就能写不需要等编辑器慢慢启动。第二数据结构化每条日记自动带上日期、时间、标签等元信息而不是像纯文本文件那样写完就变成一个无从检索的孤岛。第三可编程因为本质是个 Python 包你可以把它嵌进自动化脚本里比如下班时自动把今天的 git 提交记录汇总成日报或者定时器触发某个复盘模板。这三个特性让它在程序员、写作者、做知识管理的人手里特别顺手。这个包适合谁来用我个人的判断是如果你已经有使用终端的习惯或者日常工作流里离不开 Python 脚本那 a2d-diary 的学习成本几乎为零它给你的回报是长期、稳定、可迁移的日记数据。如果你完全不碰命令行那还是继续用图形界面工具更舒服不要为难自己。下面我先把整个包的设计思路拆开讲再逐个过语法和参数最后给几个我可以直接抄作业的实战场景以及我在真实使用中踩过的一些坑。2. 整体设计思路与安装准备2.1 为什么选择“命令 文件目录”的架构a2d-diary 的设计思路很像 Unix 哲学一件事只做一件事但把这件事做到极致。它不尝试在一个工具里塞进日历、待办、思维导图它只负责“按时间记录文本”剩下的工作全部留给文件系统和你的其他工具链。安装之后它会默认在你的用户目录下建立一个日记文件夹通常是~/diary或~/.a2d取决于版本配置里面按年份和月份划分子目录例如diary/ ├── 2024/ │ ├── 01/ │ │ ├── 2024-01-01.md │ │ ├── 2024-01-02.md │ │ └── ... │ ├── 02/ │ │ ├── 2024-02-01.md │ │ └── ... │ └── ... └── 2025/ ├── 03/ │ ├── 2025-03-15.md │ └── ...这个结构的优点你一旦开始用就会体会到哪怕哪一天 a2d-diary 这个包彻底不维护了、卸了你的日记依然是一堆标准的 Markdown 文件。任何编辑器都能打开任何脚本都能处理数据永远在你手里而不是锁在某个服务商的数据库里。每条日记文件内部也有固定的结构。默认会生成一个带 YAML 头部的 Markdown 文件头部存元信息日期、标签、天气、睡眠时长等自定义字段正文就是自由文本。这样做的好处是检索和统计可以直接解析头部字段而不用全文匹配关键词。这种设计在知识管理领域叫“内容与元数据分离”听起来高大上其实就是让程序容易读懂你的日记。2.2 安装方式与版本环境说明安装 a2d-diary 的方式非常常规走 PyPI 通道pip install a2d-diary如果你用的是国内网络环境建议指定清华镜像源速度会明显快一些pip install a2d-diary -i https://pypi.tuna.tsinghua.edu.cn/simple如果你担心污染系统级 Python 环境我更推荐装到虚拟环境里。我的习惯是创建一个专门的env目录python -m venv ~/.venvs/a2d source ~/.venvs/a2d/bin/activate pip install a2d-diary至于版本我实测用的 v1.4.xPython 3.9 到 3.12 都能正常工作。a2d-diary 的依赖非常克制核心依赖只有一个PyYAML用来解析和生成日记文件的 YAML 头部可选的增强依赖有rich格式化终端输出。如果你安装时提示缺少什么直接看报错信息补装即可不会像某些大型框架那样给你拉下来上百个依赖。装完验证一下版本号顺手创建一条测试日记确认基本盘没问题a2d --version a2d today hello, this is my first diary entry如果终端能正常输出结果并且~/diary/2025/目录下出现了当月的日记文件说明安装环节已经畅通。这时候再往下看语法和参数省得带着报错去理解后面的内容。3. 语法规则详解从能用到用顺3.1 子命令结构add、today、list、edit、delete 与 viewa2d-diary 的命令行语法走的是绝大多数现代 CLI 工具的模式主命令 子命令 若干参数。先记住六个最常用的子命令你就能覆盖 95% 的日常场景子命令作用典型用法add给指定日期新增或追加内容a2d add 2025-03-15 写了一段爬虫代码today快速写入/查看今天的日记a2d today 明天要交周报list按条件列出日记条目a2d list --tag work --from 2025-01-01edit唤起编辑器修改某一天的日记a2d edit 2025-03-15delete删除某一条或某一天的日记a2d delete 2025-03-15 --yesview渲染查看某天的日记内容a2d view 2025-03-15 --format markdowntoday子命令是最高频的操作它本质上就是add的一个快捷方式——只不过日期参数自动取当天。这意味着你完全可以只用add完成所有写入但today能帮你少敲几个字符积少成多也是效率。写入的时候内容参数可以是一次性传入的字符串也可以通过管道从其他命令接收# 直接传字符串 a2d today 完成了用户注册模块的接口联调 # 从管道接收内容 echo 修复了登录态失效的 bug原因是 Redis key 过期策略配置错误 | a2d today第二种方式厉害的地方在于它可以和任意命令组合。我经常用这种方式把监控脚本的告警信息直接写入当天的日记形成一条“异常处理时间线”后面看回顾复盘时特别直观。3.2 标签系统与 Markdown 渲染语法a2d-diary 内置了一套轻量标签语法规则很简单在正文里用标签名的方式标记。比如刚开完版本评审会work 和 meeting 都记一下。 晚上去跑步了fitness 打卡第 7 天。这里work和meeting是两个标签fitness是另一个标签。它们会被 a2d-diary 自动解析并存进 YAML 头部变成结构化的元数据。之后你用a2d list --tag work就能筛出所有工作中带work标签的日记。不要小看这一条标签是日记从“流水账”进化为“知识库”的关键一步因为检索维度一下子从时间扩展到了主题。正文内容的渲染语法不用额外学a2d-diary 直接吃标准 Markdown。你写#标题、-列表、 代码、**加粗它都支持。view子命令配合--format markdown可以在终端里直接渲染成格式化文本如果配合导出功能还能生成一篇完全兼容 Obsidian、Typora 等工具的 Markdown 文件。有个小细节值得注意标签解析默认只识别符号后跟着的字母、数字、中文和下划线遇到空格或标点就截断。所以work, 今天加班里的标签会被识别为work而不是work,。这个规则和 Twitter 的用户名分词逻辑很像简洁且实用。3.3 管道、交互模式与批量写入技巧除了直接传参a2d-diary 还支持交互模式。运行a2d today时如果不带内容参数它不会直接报错而是想办法唤起系统默认编辑器Vi/Vim、Nano或者在 macOS 上可能是 TextEdit让你在一个完整编辑器里写长内容。这个设计很适合写大段的深夜感想或者需要仔细组织语言的复盘总结。在自动化场景里管道写法比交互模式更重要。举个具体例子我写过一个脚本每天下班前把git log --since8 hours --pretty%s的输出喂给 a2d-diarygit log --since8 hours --pretty- %s | a2d today --no-echo--no-echo参数的意思是写入之后不要立刻回显整篇日记避免每次脚本运行终端刷屏。工作一天的提交记录变成一条精简的日报既真实又耗时接近零。如果你想在脚本里生成多天的日记可以写循环import subprocess dates [2025-03-01, 2025-03-02, 2025-03-03] for date in dates: cmd fa2d add {date} -- 补记的日记内容 subprocess.run(cmd, shellTrue)这个例子展示了 a2d-diary 的开放接口特性——所有功能都能被外部脚本驱动你的日记系统可以长成任何你想要的样子。4. 参数体系拆解把控制权拿回手里4.1 日期范围过滤与时间维度的高级用法list子命令最有用的参数是时间范围过滤。很多人在使用初期不知道这两个参数结果每次都用a2d list输出全部日记再看花眼。--from和--to可以把时间维度精确地切成任意区间语法非常简单# 查 2025 年 1 月整月的日记 a2d list --from 2025-01-01 --to 2025-01-31 # 查最近 7 天 a2d list --from 7d # 查 2025 年所有带 work 标签的记录 a2d list --tag work --from 2025-01-01 --to 2025-12-31关于日期值有一个非常贴心的解析规则它不仅能识别完整的YYYY-MM-DD还支持一堆口语化写法比如yesterday、today、7d表示七天前、2w两周前、1m一个月前。我第一次看到这个设计时感到非常惊喜因为这意味着你不需要在脑子里把“上个月”换算成具体的日期字符串直接传--from 1m就完事了。实现上主要有依赖 dateutil 的 relativedelta 做相对时间计算对闰年、跨月等边界情况处理得都很稳。时间维度还可以进行聚合统计。使用--stats参数你可以查看某段时间内的记录条数、标签频次、平均正文长度a2d --stats --from 1m输出类似时间段: 2025-02-15 至 2025-03-15 日记总条数: 24 标签频次: work(18), fitness(9), meeting(6) 平均正文长度: 142 字符这种统计能力非常适合月末复盘或者写 OKR 周报时快速了解过去的投入。4.2 配置文件与参数优先级机制a2d-diary 并不是把所有参数都压在命令行里它支持通过配置文件设置默认值。默认的配置文件路径在~/.config/a2d/config.yaml如果不存在运行一次任意命令后它会自动创建一个示例配置。配置文件长这样diary_path: ~/diary default_format: markdown default_tags: [] default_editor: vim date_format: %Y-%m-%d header_template: 日期: {date} 天气: 睡眠: 这里diary_path指定日记文件的根目录default_editor设置交互模式使用的编辑器header_template则可以自定义 YAML 头部的字段结构。比如你特别在意健康状况可以加一行运动: 作为默认字段逼自己每天填写。参数优先级从高到低是命令行参数 配置文件 环境变量 内置默认值。这意味着即便你在配置里写了default_editor: vim真正运行时临时想用别的编辑器只需要在命令行加一个--editor code就能覆盖配置。这个设计的逻辑和系统环境变量的 PATH 处理一脉相承配置负责定基调命令行负责开临时口子。有一个坑务必注意就是参数名里的短横线和下划线。a2d-diary 的参数定义走的是 argparse 标准所以像diary_path这样带下划长的选项在命令行里对应的参数名是--diary-path。如果你写--diary_path某些版本会直接包错而某些版本会通过allow_abbrev机制退而求其次地识别。为了避免玄学问题我的建议是统一用--diary-path这种短横线写法。4.3 模板变量与 YAML 自定义字段模板变量是 a2d-diary 参数体系中容易被忽略但极其出彩的部分。在配置文件里的header_template中你可以用大括号加变量名的方式引入动态值header_template: 日期: {date} 星期: {weekday} 时间: {time}当你运行a2d today时{date}会被替换成当天的日期{weekday}会被替换成“星期一”这样的中文星期名{time}则被替换成当前时间。这个机制让每条日记自动带上丰富的上下文无需你手动输入。除了内置变量模板还支持从环境变量取值语法是{env:HOME}例如header_template: 工作目录: {env:PWD}如果你在/home/user/project目录下运行 a2d-diary这条日记的 YAML 头部就会写上工作目录: /home/user/project。我当时用这个特性做了一个实验每次记录时把当前命令行所在的目录写进日记一个月之后回看所有的工作上下文一目了然比单纯靠回忆靠谱得多。YAML 自定义字段最经常配合的用法是后续用脚本处理。比如你想统计自己睡眠时长的变化就在配置里加睡眠: 字段每天顺手填一个数字。之后写个几行的 Python 脚本读取所有日记文件的 YAML就能画出睡眠趋势折线图。这个思路其实对所有追求量化自我的人都非常实用而且代码量不会超过 50 行。5. 实际应用案例我的三种高频用法5.1 案例一开发日志与 git 提交记录自动日报这是我最常用的场景也最能体现 a2d-diary 的自动化优势。每天下班前我会跑这样一条命令echo ## 今日提交 ~/diary/$(date %Y)/$(date %m)/$(date %Y-%m-%d).md git log --since9 hours --pretty- %s (%an) ~/diary/$(date %Y)/$(date %m)/$(date %Y-%m-%d).md但手动敲命令还是太土了。更优雅的方式是写成一个小 Shell 函数放进~/.bashrc或~/.zshrcdiary_report() { { echo ## 今日提交; git log --since9 hours --pretty- %s; } | a2d today --no-echo }这样每次只需要敲diary_report当日提交历史就以 Markdown 形式追加进了日记。一周以后你的日报、周报、月度总结素材全都在那里躺着写的时候只需要复制粘贴加少量润色效率提升是很明显的。配合--stats还能看出自己一周内的工作密度。我试过连续两周统计发现明显感觉到“忙疯了”的那周其实 git 提交记录并不多真正占据时间的是评审和会议。这种数据带来的自我认知修正比单纯拍脑袋准得多。5.2 案例二习惯打卡与标签统计把 a2d-diary 当作习惯打卡工具的体验也很丝滑。我养成了每天晚上睡觉前写一条打卡日记的习惯a2d today 跑步 5 公里fitness读了《金字塔原理》第一章reading没有喝含糖饮料health过一段时间后用标签统计看看频率a2d --stats --tag fitness --from 30d得出的结果可能是时间段内 fitness 标签出现数: 18有了这个数据就不需要再单独下载习惯打卡 App数据在自己的文件里格式完全开放想怎么分析怎么分析。如果有人想玩得更花还可以用 Python 读取 YAML 头部写进 SQLite用 Grafana 之类的工具做可视化看板但这就属于锦上添花了。5.3 案例三与 Crontab 结合定时收集灵感第三个案例适合脑力工作者。我在终端里跑着一个定时任务每天上午九点提醒自己写晨间日记标题模板带有当天的日期和天气占位符内容留空晚上再补填这样既不打断上午的工作节奏又记得预留位置。更进阶一点的玩法是用 Python 脚本配合定时任务把每天某时段收到的输入自动归档# collect_notes.py from a2d_diary import Client client Client() note input(记录一条灵感: ) client.add(contentnote, tags[idea])配合cron在固定时间运行这样可以把日常碎片记录全部收敛到一个地方。虽然用输入函数不太灵活但至少给了一个跨应用整合的起点想接 Telegram bot 或 web 表单都行。5.4 价值反思日记系统应当为十年后的你服务用 a2d-diary 一段时间后我对它的价值有了更深的认识。它不像社交软件那样追求即时反馈它的回报周期是以月和年为单位的。坚持使用 100 天后你拥有的不只是一堆 Markdown 文件而是一条可以拉回任意时间点的主线记忆。这也是我特别偏爱它的原因。在数据塑造成本越来越低的时代能有意识地构建自己的时间数据库并用标准的、可迁移的格式保存是一种非常理性的信息管理习惯。它的价值在未来而不是当下。6. 常见问题与排查技巧实录6.1 安装后终端找不到命令这是最高频的报错——你执行pip install a2d-diary一切顺利但是运行a2d却提示“command not found”。原因几乎总是同一个Python 的 Scripts 目录没有加入 PATH。排查方法是先看安装位置pip show a2d-diary | grep Location然后检查该目录下的bin或Scripts文件夹是否存在a2d可执行文件。在 Linux/macOS 上如果路径形如/usr/local/python3.11/bin就把它加进~/.bashrcexport PATH/usr/local/python3.11/bin:$PATH在 Windows 上通常是找到C:\Python311\Scripts加进系统环境变量。有些场景下单纯重启终端也能解决因为部分操作系统的 PATH 刷新有延迟。6.2 中文乱码问题终端里查看日记时中文变成一坨乱码排除日记文件本身的编码问题后大概率是终端会话的编码不对。在 Linux 下执行export LANGzh_CN.UTF-8 export LC_ALLzh_CN.UTF-8Windows PowerShell 用户则可以先执行chcp 65001如果你的日记文件本身保存成了 GBK那乱码根源在文件编码不是终端问题。这时需要转换编码iconv -f GBK -t UTF-8 input.md output.md强烈建议从一开始就在配置文件里强制 UTF-8 输出a2d-diary 本身默认就是 UTF-8乱码多数是因为操作系统或终端设置背锅。6.3 --from 7d 查空结果--from 7d这个相对时间参数看起来很直观但有些版本对d后缀的解析有限制如果传7day、7 days这类变体可能无法识别最终返回空列表。解决方法是查看内置帮助确认当前版本支持的时间单位a2d list --help如果确实不支持兜底方案是直接用 Python 生成精确日期传入a2d list --from $(date -d 7 days ago %Y-%m-%d)macOS 上的date命令和 Linux 的-d写法略有不同需要用date -v-7d %Y-%m-%d。这些细节平时不起眼但在脚本里一配错就是整套流程白跑。6.4 YAML 头部解析报错如果你手动编辑过日记文件a2d-diary 在读取时可能会报 YAML 解析错误。最常见的原因是冒号后面没有加空格比如日期: 2025-03-15 # 正确写法是冒号后有空格 天气:晴 # 晴前面没空格YAML 要求键值对里的冒号只能用于分隔但它后面必须跟一个空格。这不是 a2d-diary 的问题是 YAML 语法本身的规矩。补上一个空格或引号解析就恢复了。如果你写了很多行不想手动改可以用 Python 的ruamel.yaml库做一次自动化修复。6.5 自动脚本参数传递陷阱在用 Python 脚本调用 a2d-diary 子命令时最容易忽略的是内容里包含空格和引号。直接用字符串拼接整条命令很容易因为引号匹配关系出错。正确做法是使用列表参数传递import subprocess subprocess.run([a2d, today, 这段内容有空格也安全])这样就完全不需要担心 shell 二次解析。这个经验适用于任何让你运行外部命令的 Python 脚本不只是 a2d-diary。6.6 性能问题日记多了卡顿怎么办当日记文件超过几百个、标签数量破千时a2d list的响应时间会明显下降。这几乎是必然的因为它是逐个文件扫描而不是走数据库索引。但有一个很实用的优化技巧利用--from和--to把扫描范围缩小到特定几个月性能会立竿见影。我现在的日记文件总量超过八百篇只要按季度查速度依然很快。如果你确实需要跨全库搜索可以写个 Python 脚本把历史 YAML 头数据导入 SQLite之后查询全部走 SQL响应基本就是毫秒级。这个进阶方案等你有需要了再折腾初期别把精力花在优化上。7. 一点个人的经验总结我在实际使用 a2d-diary 的过程中有几点体会想跟想入坑的朋友分享。第一不要太早追求复杂的自定义模板和参数。刚开始只记流水账习惯每天写的那一下自然发生了再去折腾配置。很多人一上来就配了一堆字段结果坚持不下来这其实不是工具的问题是步子迈太大了。第二标签体系要在用中长出来而不是一开始设计好。我早期设了十个固定标签后来发现实际用的只有三个反而是后来随手加的 idea 和 bug 变得最有价值。第三善用管道写自动化让日记变成工作流的副产物而不是给自己增加额外的录入负担。一条优秀的日记轻量到不会打扰你的任何工作节奏这才是它能长期坚持的原因。最后分享一个扩展玩法a2d-diary 生成的 Markdown 文件本身是可以直接放进 Obsidian 仓库拖拽引用的。我用 Telegraf 服务把日记文件和 mySQL 同步了一份勉强算是拥有了一个可全文搜索的时间摘要索引。这只是个参考你完全可以按自己的需求把这份日记数据接到其他工具链里。工具是死的你的想象才是上限。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询