使用 PowerShell 一键更新 Hexo 文章的 updated

引言 使用 CI ( 例如 GitHub Actions ) 自动部署 Hexo 会导致所有文章 更新于 时间统一变成 GitHub Actions 生成部署的时间, 有3中解决方法:
    给每篇文章手动添加 updated 字段, 并每次更新文章, 手动更新 在 CI 的步骤中 利用 git log 通过 touch 的方式 修改文件的更新时间为 最后一次 commit 的时间 ( 见 Hexo 笔记 ) 本文 利用 powershell 一键更新 updated, 其实也是利用的 git log
主要是考虑到 文件属性的修改时间 不便查看,以及当换电脑时, 重新从 git 仓库 clone 下来的文件 是没有 更新时间 属性的。
但每次手动维护更新时间比较麻烦,于是编写 powershell 脚本 来达到自动更新 updated.ps1 在 Hexo 根目录 保存并执行此脚本即可
updated.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

$fileEncoding = "UTF8";

# https://www.manongdao.com/article-846164.html
Function Convert-FromUnixDate ($UnixDate) {
[timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($UnixDate))
}

#$OutputEncoding = New-Object -typename System.Text.UTF8Encoding

#[console]::outputencoding=[system.text.encoding]::utf8

#Write-Host("请将本脚本在 Hexo 根目录执行");
#Write-Host("开始更新 updated");

$fileNum = 0;
Get-ChildItem -Path "./source/_posts" -recurse *.md | ForEach-Object -Process{
$fileNum = $fileNum + 1;
if ($_ -is [System.IO.FileInfo]) {

$filePath = $_.FullName;
Write-Host('{0}. {1}' -f $fileNum, $filePath);

$lineNum = 0; # yaml 格式占据行数
$yamlStartEndNum = 0;
$existUpdated = $false;
$updatedNum = 0;
$newstreamreader = New-Object System.IO.StreamReader($filePath);
while (($readeachline = $newstreamreader.ReadLine()) -ne $null) {
$lineNum = $lineNum + 1;
$temp = $readeachline -replace " ","" -replace "\n",""
if ($temp -match "---") {
$yamlStartEndNum = $yamlStartEndNum + 1;
}
if ($readeachline.Contains("updated:")) {
$existUpdated = $true;
$updatedNum = $lineNum;
}
if ($yamlStartEndNum -ge 2) {
# yaml end
break;
}
}
$newstreamreader.Dispose();

$filedata = Get-Content -Path $filePath -Encoding $fileEncoding;
$oldYamlStr = $filedata | Select-Object -First $lineNum

# git log format: https://www.cnblogs.com/ckAng/p/11205055.html https://git-scm.com/docs/git-log
# 此文件 最后一次 commit 的 Unix时间戳
$dateUpdated = git log -1 --format='%ct' $filepath
$dateUpdated = Convert-FromUnixDate $dateUpdated
$dateUpdated = $dateUpdated.ToString("yyyy-MM-dd HH:mm:ss");
$newUpdated = "updated: " + $dateUpdated;

#Write-Host("newUpdated: " + $newUpdated)

$newYamlStr = ""
# 注意: yamlStr 是一个数组, 每一个元素为一行字符串
$tempOldYamlStr = $oldYamlStr;
if ($existUpdated) {
#Write-Host($yamlStr[$updatedNum-1])
$oldUpdated = $oldYamlStr[$updatedNum-1];
$tempOldYamlStr[$updatedNum-1] = $oldYamlStr[$updatedNum-1] -replace $oldUpdated,$newUpdated
}else {
# 修改 yaml 结束行
# TODO: 好像取到的这一行不包括 最后的换行符, 导致加一个 换行 反而多了, 不过为了保险, 还是加上一个换行
$tempOldYamlStr[$lineNum-1] = $newUpdated + $([System.Environment]::NewLine) + "---" + $([System.Environment]::NewLine)
}
$newYamlStr = $tempOldYamlStr

Write-Output $newYamlStr


$newFiledata = $newYamlStr + $filedata[$lineNum..$filedata.count]
$newFiledata | Set-Content -Path $filePath -Encoding $fileEncoding

}
}

#Write-Host("更新 updated 完成");

1
./updated.ps1
Q&A 补充 参考 感谢帮助! PowerShell教程™ PowerShell与Write-Host和Write-Output之间的区别? | 经验摘录 PowerShell 数组(Array)_公众号:SQLServer-CSDN博客_powershell 数组 hexo自动更新文章修改时间 | Black Flies PowerShell 中文博客 – 收集和分享 Windows PowerShell 相关教程,技术和最新动态 在Powershell脚本中添加换行符(换行符) | 经验摘录 PowerShell 运算符详解_weixin_33785972的博客-CSDN博客 使用PowerShell读取文件数据_culuo4781的博客-CSDN博客 powershell字符串操作 - 一个有故事的devops - 博客园