# 下载 Markdown 中的掘金外链图片到 source/images/,并替换链接为站内路径 param( [string]$MdPath = "c:/Users/Administrator/Desktop/新建文件夹/blog/source/_posts/Git使用教学.md", [string]$OutDir = "c:/Users/Administrator/Desktop/新建文件夹/blog/source/images" ) $ErrorActionPreference = "Stop" New-Item -ItemType Directory -Force -Path $OutDir | Out-Null $content = Get-Content -Path $MdPath -Raw -Encoding UTF8 # 匹配 ![alt](url) 中的掘金图片地址 $pattern = '!\[[^\]]*\]\((https://p3-juejin\.byteimg\.com/[^)\s]+)\)' $imgMatches = [regex]::Matches($content, $pattern) $map = @{} # url -> /images/xxx.webp $count = 0 $failed = @() foreach ($m in $imgMatches) { $url = $m.Groups[1].Value if ($map.ContainsKey($url)) { continue } # 用 URL 路径最后一段中 "~" 之前的部分作为文件名(即图片 hash) $seg = ($url -split '/')[-1] $hash = ($seg -split '~')[0] if ([string]::IsNullOrEmpty($hash)) { $failed += "无法解析文件名: $url" continue } $file = $hash + '.webp' $dest = Join-Path $OutDir $file try { curl.exe -s -L --max-time 30 -o $dest $url if ((Test-Path $dest) -and ((Get-Item $dest).Length -gt 0)) { $map[$url] = '/images/' + $file $count++ Write-Host "[OK] $file <- $url" } else { $failed += "下载为空: $url" } } catch { $failed += "下载异常: $url -> $_" } } # 替换 Markdown 中的外链 foreach ($kv in $map.GetEnumerator()) { $content = $content.Replace($kv.Key, $kv.Value) } # 写回(UTF-8 无 BOM) [System.IO.File]::WriteAllText($MdPath, $content, [System.Text.UTF8Encoding]::new($false)) Write-Host "" Write-Host "完成:成功下载 $count 张,失败 $($failed.Count) 张" if ($failed.Count -gt 0) { Write-Host "失败列表:" $failed | ForEach-Object { Write-Host " - $_" } }