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

2022-04-01 17:24:11 浏览数 (1)

引言

使用 CI ( 例如 GitHub Actions ) 自动部署 Hexo 会导致所有文章 更新于 时间统一变成 GitHub Actions 生成部署的时间, 有3中解决方法:

  1. 给每篇文章手动添加 updated 字段, 并每次更新文章, 手动更新
  2. 在 CI 的步骤中 利用 git log 通过 touch 的方式 修改文件的更新时间为 最后一次 commit 的时间 ( 见 Hexo 笔记 )
  3. 本文 利用 powershell 一键更新 updated, 其实也是利用的 git log

主要是考虑到 文件属性的修改时间 不便查看,以及当换电脑时, 重新从 git 仓库 clone 下来的文件 是没有 更新时间 属性的。 但每次手动维护更新时间比较麻烦,于是编写 powershell 脚本 来达到自动更新

updated.ps1

在 Hexo 根目录 保存并执行此脚本即可

代码语言:javascript复制
$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 完成");
代码语言:javascript复制
./updated.ps1

参考

感谢帮助!

  • 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 - 博客园

本文作者: yiyun

本文链接: https://cloud.tencent.com/developer/article/1970906

版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

0 人点赞