概述
本文介绍一个使用Go语言编写的脚本,其功能是清理指定目录中未被Markdown文件引用的图片。该脚本通过读取Markdown文件中的图片引用,与存储在特定目录下的所有图片进行对比,将未引用的图片移动到另一个指定的目录中。此脚本适用于需要维护图片库,确保其中只包含有效引用图片的场景。
功能和实现
命令行参数
脚本通过命令行参数接收两个目录路径:
imgDir
:存储Markdown文件中引用图片的目录。delDir
:用于存放未引用图片的目录。
主要步骤
- 解析命令行参数:使用
flag
包解析命令行参数,获取图片目录和删除目录的路径。 - 读取Markdown文件:遍历当前目录下的所有文件,识别
.md
扩展名的文件。 - 提取图片引用:对于每个Markdown文件,使用正则表达式提取文件中引用的图片路径,并将这些路径存储在一个切片中。
- 获取所有图片文件:读取图片目录下的所有文件和文件夹,存储在一个切片中。
- 对比和移动未引用图片:遍历所有图片文件,检查它们是否在Markdown文件中被引用。如果未被引用,则将其移动到删除目录。
关键函数
extractReferencedImages
:从Markdown文件中提取所有图片引用。isContained
:检查图片是否在引用列表中。moveFile
:移动文件到新位置,并删除原始文件。
使用说明
- 将脚本放在包含Markdown文件的目录中。
- 运行脚本,并指定图片目录和删除目录的路径。
- 脚本将自动处理并移动未引用的图片。
代码
package main
import (
"flag"
"fmt"
"os"
"path/filepath"
"regexp"
)
func main() {
defer pressKeyToExit()
// 解析命令行参数
imgDirPtr := flag.String("i", "pic", "Image directory path")
delDirPtr := flag.String("d", ".del", "Invalid image deletion directory path")
flag.Parse()
picDir := *imgDirPtr // 图片存储的目录
delDir := *delDirPtr // 要移动未引用图片的目录
// 获取当前工作目录
dir, err := os.Getwd()
if err != nil {
fmt.Println("获取文件夹失败:", err)
return
}
// 读取目录下的所有文件和文件夹
files, err := os.ReadDir(dir)
if err != nil {
fmt.Println("读取文件夹失败:", err)
return
}
referencedImages := &[]string{}
// 遍历文件和文件夹
for _, file := range files {
// 检查文件是否以.md结尾
if filepath.Ext(file.Name()) == ".md" {
// 获取Markdown文件中所有引用的图片
referencedImages = extractReferencedImages(referencedImages, file.Name())
}
}
// 获取目录中的所有图片文件
allImages, err := os.ReadDir(picDir)
if err != nil {
fmt.Println("读取文件夹失败:", err)
return
}
// 确保删除目录存在
if _, err := os.Stat(delDir); os.IsNotExist(err) {
os.Mkdir(delDir, 0755)
}
// 查找未引用的图片
for _, img := range allImages {
if img.IsDir() {
continue
}
imgName := img.Name()
if contained, _ := isContained(*referencedImages, filepath.Join(picDir, imgName)); !contained {
// 移动未引用的图片到删除目录
err = moveFile(filepath.Join(picDir, imgName), filepath.Join(delDir, imgName))
if err != nil {
fmt.Println(err)
}
}
}
fmt.Println("未引用图片清理完成")
}
func pressKeyToExit() {
fmt.Println("\n按任意键退出...")
var input string
fmt.Scanln(&input)
}
// extractReferencedImages 从Markdown文件中提取所有图片引用
func extractReferencedImages(referencedImages *[]string, mdFile string) *[]string {
content, err := os.ReadFile(mdFile)
if err != nil {
fmt.Println("读取文件失败:", err)
return referencedImages
}
re := regexp.MustCompile(`!\[.*?\]\((.*?)\)`)
matches := re.FindAllStringSubmatch(string(content), -1)
for _, match := range matches {
matchPath, err := filepath.Abs(match[1])
if err != nil {
fmt.Println("文件不存在:", err)
}
*referencedImages = append(*referencedImages, matchPath)
}
return referencedImages
}
// isContained 检查图片是否在引用列表中
func isContained(slice []string, item string) (bool, error) {
for _, s := range slice {
itemPath, err := filepath.Abs(item)
if err != nil {
return false, err
}
if s == itemPath {
return true, nil
}
}
return false, nil
}
// moveFile 移动文件到新位置
func moveFile(srcPath, destPath string) error {
// 使用 os.Rename 移动文件
err := os.Rename(srcPath, destPath)
if err != nil {
return fmt.Errorf("无法移动文件: %s", err)
}
fmt.Printf("清理未引用图片 '%s' 到 '%s'\n", srcPath, destPath)
return nil
}
结论
这个Go语言程序提供了一个高效的方式来管理Markdown文件中的图片引用,帮助用户清理未使用的图片,从而节省存储空间并保持文件结构的整洁。