我在使用obsidian这个笔记工具插件已经安装到103个了,使用效率一般般,偶尔记录个日记主要是几类灵感,打开个obsidian也不是很方便,这两天想使用obsdian的cil命令行,但它还是需要主程序obsidian打开的情况下,同样也不够方便,所以CLI命令更适合给AI调用库笔记使用,可以减少大模型的token的消耗。
于是昨天让AI帮我调试一个脚本,用了一白天一晚上,做了一个powershell的ps1脚本,就是让listary使用命令加参数的方式向obsidian里添加笔记,再也不用因为一个小事情要记录,要打开103个插件的obsdian了。效果不错,放上来分享。
效果:通过Listary 命令+内容(符号分割,建立多条普通记录、无序列表、任务列表),建立一个文件名为"日记-年-月-日-周几-周数.md"的文件,可以让obsidian识别的笔记。
目的:不用打开obsidian再干这点临时的小活了
1、listary使用命令
obs 第一条内容-第二条内内容 --第三条内容--第四条内容【】第五条内容[]第六条内容#标签1 #标签2。内容里可以加常规的标点符号。只要不加-,--,【】,[],#,这几个符号就行。目前我还没有需要,如果有需要可以调试,你也可以用这个脚本继续调试。
2、命令解释和效果:
普通内容,第一条是在命令提示关键词obs后加空格加内容就可以,后边的加"-“一个字符普是新加加一条普通内容;”--“两个字符就是添加一条无序列表,”【】“和”[]"这两种字符代表添加一条任务列表 “#标签 "代表#号+文案+空格是添加标签的,并会被添加到笔记的yaml属性区。
命令后的内容可以前后调换使用,没有使用顺序要求,会有个别情况输入非常不规范导致添加的标签可能没有被添加到yaml区或yaml标签区被[xxxx]这种符号嵌套异常。不过一般人不会像我这么抽风容易干出这个事情。![]()
![]()
效果如下:
3、脚本如下:ps:又修改一版
使用:新建一个txt文件,把代码粘贴进去,保存成ob_append.ps1文件,编辑格式为UTF-8 BOM,很重要。
# 🌟 核心拦截机制:彻底舍弃 param 绑定,防止 Listary 传入的 '-' 被系统误认为参数而崩溃
$userInput = $args -join " "
try {
# 1. 强制 UTF-8 编码写入 (不带BOM,维持文件哈希纯净)
$utf8NoBom = New-Object System.Text.UTF8Encoding $false
# 2. 获取时间与路径变量
$dateObj = Get-Date
$dateStr = $dateObj.ToString("yyyy-MM-dd")
$weekDay = $dateObj.ToString("ddd", [System.Globalization.CultureInfo]::CreateSpecificCulture("zh-CN"))
$dayOfWeek = [int]$dateObj.DayOfWeek
if ($dayOfWeek -eq 0) { $dayOfWeek = 7 }
$weekNum = [math]::Floor(($dateObj.DayOfYear - $dayOfWeek + 10) / 7)
$fileName = "日记-$dateStr-$weekDay-$weekNum.md"
$path = "D:\用户目录\Documents\笔记库\日记\$fileName"
$templatePath = "D:\用户目录\Documents\笔记库\资源\模板\T_日记模板.md"
$h = $dateObj.ToString("HH")
$m = $dateObj.ToString("mm")
$dateTimeStr = $dateObj.ToString("yyyy-MM-dd HH:mm")
# 3. 清洗输入内容
$text = $userInput -replace '^"|"$', ''
$text = $text -replace '\{\{date\}\}\s*', ''
$text = $text.Trim()
# 4. 提取标签
$foundTags = @()
$extractRegex = '#([a-zA-Z0-9_\u4e00-\u9fa5]+(?:/[a-zA-Z0-9_\u4e00-\u9fa5]+)?)(?=\s|$)'
foreach ($match in [regex]::Matches($text, $extractRegex)) {
$foundTags += $match.Groups[1].Value
}
if ($foundTags.Count -gt 0) {
$removeRegex = '#[a-zA-Z0-9_\u4e00-\u9fa5]+(?:/[a-zA-Z0-9_\u4e00-\u9fa5]+)?(?=\s|$)\s*'
$text = ($text -replace $removeRegex, '').Trim()
$text = $text -replace ' {2,}', ' '
}
# 5. 指令解析 (全局切割引擎)
$text = $text -replace '\\n', '<<BREAK>>'
$text = $text -replace "`r`n|`n", '<<BREAK>>'
$text = $text -replace '--', '<<LIST>>'
$text = $text -replace '-', '<<BREAK>>'
$text = $text -replace '[\[【][\]】]', '<<TASK>>'
$text = $text -replace '^<<BREAK>>\s*', ''
$NL = "`n"
$TAB = "`t"
$text = $text -replace '<<LIST>>\s*', ($NL + $TAB + '- ')
$text = $text -replace '<<BREAK>>\s*', ($NL + $TAB)
$text = $text -replace '<<TASK>>\s*', ($NL + $TAB + '- [ ] ')
if ($text -eq "") {
$formattedText = ""
} else {
$formattedText = $TAB + $text + $NL
$formattedText = $formattedText -replace "^$TAB$NL$TAB", $TAB
}
$finalContent = ""
# ---- 6. 组装内容分支:追加或新建 ----
if (Test-Path $path) {
$content = Get-Content $path -Raw -Encoding UTF8
$content = $content -replace "`r`n", "`n"
if ($formattedText -ne "") {
# 🚀 修复核心:移除判断“同一小时”的合并逻辑!
# 强制每次追加都生成全新的 - HH:mm 时间戳,并确保前面有且仅有一个空行,完美适配 Thino
if ($content.Length -gt 0) {
if ($content.EndsWith($NL + $NL)) { $prefix = '' }
elseif ($content.EndsWith($NL)) { $prefix = $NL }
else { $prefix = $NL + $NL }
} else { $prefix = '' }
$toAppend = $prefix + "- " + $h + ":" + $m + " " + $NL + $formattedText
$content += $toAppend
}
$finalContent = $content
} else {
$initContent = ''
if (Test-Path $templatePath) {
$initContent = Get-Content $templatePath -Raw -Encoding UTF8
$initContent = $initContent -replace "`r`n", "`n"
$initContent = $initContent -replace '<%\s*tp\.file\.creation_date\(\)\s*%>', $dateTimeStr
$initContent = $initContent -replace '<%\s*tp\.file\.last_modified_date\(\)\s*%>', $dateTimeStr
# 🌟 终极强悍的双引擎天气模块 🌟
try {
$weatherUrl = "https://wttr.in/%E5%9C%9F%E9%BB%98%E7%89%B9%E5%B7%A6%E6%97%97?lang=zh&format=%l:+%c+%C+|+%t+|+体感温度+%f+|+湿度+%h+|+风速+%w+|+月相+%m"
$weatherStr = (Invoke-RestMethod -Uri $weatherUrl -Headers @{'User-Agent'='curl'} -TimeoutSec 5 -ErrorAction Stop).Trim()
} catch {
$weatherStr = "获取天气失败"
}
$initContent = $initContent -replace '(?s)<%\*.*?wttr\.in.*?%>', $weatherStr
if (-not $initContent.EndsWith($NL)) { $initContent += ($NL + $NL) } else { $initContent += $NL }
}
$toAppend = $initContent + "- " + $h + ":" + $m + " " + $NL + $formattedText
$finalContent = $toAppend
}
# ---- 7. 属性区 (YAML) 标签智能写入 ----
if ($foundTags.Count -gt 0) {
$tagsToAdd = @()
foreach ($t in $foundTags) {
if ($finalContent -notmatch "(?m)^ - " + [regex]::Escape($t) + "\s*$") {
$tagsToAdd += $t
}
}
if ($tagsToAdd.Count -gt 0) {
$tagStr = ""
foreach ($t in $tagsToAdd) { $tagStr += " - $t$NL" }
if ($finalContent -match "\A---\n") {
if ($finalContent -match "(?m)^tags:\n") {
$finalContent = $finalContent -replace "(?m)^(tags:\n)", "`$1$tagStr"
} else {
$finalContent = $finalContent -replace "\A---\n", "---${NL}tags:${NL}${tagStr}"
}
} else {
$finalContent = "---${NL}tags:${NL}${tagStr}---${NL}" + $finalContent
}
}
}
# 8. 彻底写入文件
[System.IO.File]::WriteAllText($path, $finalContent, $utf8NoBom)
} catch {
$errorPath = "D:\用户目录\Documents\笔记库\日记\error_log.txt"
$errorMsg = "发生时间: $(Get-Date)`n错误内容: $($_.Exception.Message)`n出错代码行: $($_.InvocationInfo.ScriptLineNumber)`n-----------------`n"
[System.IO.File]::AppendAllText($errorPath, $errorMsg, (New-Object System.Text.UTF8Encoding $false))
}
4、脚本解释:
4.1 自动在 "x盘:\aaa\bbb\obsidian库\日记\"路径下建立名为"日记-2026-06-11-周四-24.md" 这样的笔记。原来我只有 “日记-2026-06-11”,只对文件名排序有好处,新的命名可以知道是哪个月周几,一直第几个周了。此路径可以自定义,把脚本里的路径都统一改了
4.2 自动添加yaml创建和修改时间,通过https://wttr.in,自动添加一个天气内容。默认添加一个#日记的标签,其它标签在命令里添加
4.3 兼容obsidian插件Thino显示,在这个插件里,笔记内容要加时间和内容的一个制表符,会显示在thino插件区。这样就是一些笔记的标题格式显示不太好。
这个效果我之前用cmd命令调试,只能obsidian笔记区显示,就这个搞了我一天的时间,晚上我回去让ai用ps1脚本调试,一下子就正常了。
5、脚本调用
5.1 在listay的选项里找到命令点右侧下面的+号新建命令,按图添加内容,关键字可以自定义,标题可以自定义,路径:powershell.exe,参数:-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "D:\用户目录\Documents\笔记库\资源\脚本\ob_append.ps1" "{query}",注意把引号也要加入去,路径就是上面让你新建txt改成ps1文件脚本的路径。可以按我的放在笔记库的资源文件夹里。
5.2 静默执行,可以先不用打勾,看看笔记有问题吗,没有问题再勾上。然后双ctrl键,激活listary启动器,输入第一天的命令试一下,就可以无感记录了。
如图:
6、关于记录时间的说明
6.1
一般的的记录是添加内容带格式,我这为了兼容thino,主要是要在记录时添加时间。而一般的添加时间试,就是什么时候添加内容,就加一个时间,我感觉这样太琐碎了,所以我把时间修改了一下。
让他按小时记录,只要在一个小时内,就按这一个小时内第一条添加的时间收集,不再添加当前时间。超过一个小时的,就是超过这个整点的,又让他在当前时间新创建一个时间标签儿,添加新内容。
原来兼容显示一小时内集中收集有个问题,就是再添加记录时,在插件thino里不显示,得在插件修改保存才可以。所以新的方案不再集中到一小时收集了,只要新添加记录内容就会添加一个时间,这样就都会显示在thino里。
不过有一个小缺陷就是单行的时候,thino会跟在时间后面,此脚本还是会单独列在时间下面。






