侧边栏壁纸
博主头像
人生短短几个秋

行动起来,活在当下

  • 累计撰写 45 篇文章
  • 累计创建 20 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

批量替换MD文件中的图片为新的地址

人生短短几个秋
2025-01-25 / 0 评论 / 0 点赞 / 24 阅读 / 0 字

代码仓库

Github地址:https://github.com/cqlijilong/replace-md-images

Gitee地址:https://gitee.com/cqlijilong/replace-md-images


完整代码

以下是完整的代码说明,包括每个部分的功能和作用,帮助您清楚了解代码的工作原理。

import os
import re

# 用户可配置:旧链接和新链接前缀
old_link_prefix = "https://old.example.com/md-images/raw/master/"
new_link_prefix = "https://new.example.com/md-images/"

# 用户可配置:md文件夹路径
markdown_files_dir = "path-to-markdown-files"

# 动态生成的正则表达式
image_url_pattern = re.compile(rf'!\[.*?\]\({re.escape(old_link_prefix)}(.*?)\)')

# 修改链接计数器
modified_link_count = 0

def update_markdown_links(old_prefix, new_prefix):
    """
    遍历 markdown 文件,更新图片链接并统计修改次数。
    :param old_prefix: 旧链接前缀
    :param new_prefix: 新链接前缀
    """
    global modified_link_count
    updated_links = []

    for root, _, files in os.walk(markdown_files_dir):
        for file in files:
            if file.endswith(".md"):
                file_path = os.path.join(root, file)
                with open(file_path, "r", encoding="utf-8") as f:
                    content = f.read()

                # 查找并替换图片链接
                updated_content = content
                matches = image_url_pattern.findall(content)
                for match in matches:
                    old_url = f"{old_prefix}{match}"
                    new_url = f"{new_prefix}{match}"
                    updated_content = updated_content.replace(old_url, new_url)
                    updated_links.append((file_path, old_url, new_url))

                # 如果文件内容有变化,写回文件
                if updated_content != content:
                    with open(file_path, "w", encoding="utf-8") as f:
                        f.write(updated_content)

                    # 增加修改的链接数量
                    modified_link_count += len(matches)

    # 打印更新的链接信息
    print("更新的图片链接:")
    for file_path, old_url, new_url in updated_links:
        print(f"文件: {file_path}\n旧链接: {old_url}\n新链接: {new_url}\n")

if __name__ == "__main__":
    # 更新 markdown 文件中的图片链接
    update_markdown_links(old_link_prefix, new_link_prefix)

    # 打印修改链接的总数量
    print(f"总共修改了 {modified_link_count} 个链接。")

代码说明

1. 导入模块

import os
import re
  • os 模块:用于操作文件和目录,包括路径拼接、文件夹遍历等功能。
  • re 模块:用于正则表达式操作,匹配和提取 Markdown 文件中图片链接的动态部分。

2. 配置变量

old_link_prefix = "https:/old.example.com/md-images/raw/master/"
new_link_prefix = "https://new.example.com/md-images/"
markdown_files_dir = "markdown-files"
  • old_link_prefix:表示 Markdown 文件中引用的旧链接的公共部分。
  • new_link_prefix:表示新的链接前缀,更新后的图片链接将以此开头。
  • markdown_files_dir:存储 Markdown 文件的文件夹路径,程序会遍历该目录中的所有 .md 文件。

3. 正则表达式编译

image_url_pattern = re.compile(rf'!\[.*?\]\({re.escape(old_link_prefix)}(.*?)\)')
  • 功能:生成一个正则表达式,用于匹配 Markdown 中的图片链接,并提取动态部分。

  • 正则解析

  • !\[.*?\]:匹配 Markdown 图片引用的描述部分(![...description...])。

  • \(\):匹配 Markdown 图片链接的括号部分。

  • re.escape(old_link_prefix):将用户指定的旧链接前缀转义为正则表达式的安全字符串。

  • (.*?):匹配旧链接前缀后的动态部分,并捕获为一个组。


4. 链接更新函数

def update_markdown_links(old_prefix, new_prefix):
    """
    遍历 markdown 文件,更新图片链接并统计修改次数。
    :param old_prefix: 旧链接前缀
    :param new_prefix: 新链接前缀
    """
  • 该函数的作用是遍历 Markdown 文件,将匹配的图片链接替换为新链接,并统计总共修改的链接数量。

5. 遍历 Markdown 文件

for root, _, files in os.walk(markdown_files_dir):
    for file in files:
        if file.endswith(".md"):
            file_path = os.path.join(root, file)
            with open(file_path, "r", encoding="utf-8") as f:
                content = f.read()
  • os.walk(markdown_files_dir)

    :递归遍历指定目录下的所有文件和子目录。

  • root:当前目录路径。

  • _:当前目录下的子目录列表(未使用)。

  • files:当前目录下的文件列表。

  • 文件过滤:只处理 .md 格式的文件。


6. 查找和替换链接

matches = image_url_pattern.findall(content)
for match in matches:
    old_url = f"{old_prefix}{match}"
    new_url = f"{new_prefix}{match}"
    updated_content = updated_content.replace(old_url, new_url)
    updated_links.append((file_path, old_url, new_url))
  • image_url_pattern.findall(content)
  • 使用正则表达式查找 Markdown 文件中所有符合旧链接前缀的图片链接。
  • 提取每个链接中的动态部分(match)。
  • 构造新链接
  • old_prefixnew_prefix 拼接旧链接和新链接。
  • 使用 str.replace 将旧链接替换为新链接。
  • 记录修改信息
  • 将修改的文件路径、旧链接和新链接保存到 updated_links 列表中,便于后续打印。

7. 写回文件

if updated_content != content:
    with open(file_path, "w", encoding="utf-8") as f:
        f.write(updated_content)

    modified_link_count += len(matches)
  • 判断内容是否变化:只有在文件内容发生变化时才会写回文件。
  • 计数修改的链接:每次替换操作后,增加 modified_link_count

8. 打印修改结果

print("更新的图片链接:")
for file_path, old_url, new_url in updated_links:
    print(f"文件: {file_path}\n旧链接: {old_url}\n新链接: {new_url}\n")

print(f"总共修改了 {modified_link_count} 个链接。")
  • 打印每个文件中修改的链接信息,包括:
  • 文件路径。
  • 修改前的旧链接。
  • 修改后的新链接。
  • 最后输出总共修改的链接数量。

代码工作流程

  1. 用户配置旧链接前缀和新链接前缀。

  2. 遍历 markdown-files 目录中的所有 .md 文件。

  3. 在每个文件中查找以

    old_link_prefix
    

    开头的图片链接:

  4. 提取链接中的动态部分。

  5. 将旧链接替换为以 new_link_prefix 开头的新链接。

  6. 将修改后的内容写回文件。

  7. 统计修改的链接总数,并打印详细信息。


输出示例

假设 Markdown 文件如下:

![image1](https://old.example.com/md-images/2023/08/29/image1.png)
![image2](https://new.example.com/md-images/2023/08/30/image2.jpg)

运行结果(地址已处理):

更新的图片链接:
文件: markdown-files/example.md
旧链接: https://old.example.com/md-images/2023/08/29/image1.png
新链接: https://new.example.com/md-images/2023/08/29/image1.png

文件: markdown-files/example.md
旧链接: https://old.example.com/md-images/2023/08/30/image2.png
新链接: https://new.example.com/md-images/2023/08/30/image2.png

总共修改了 2 个链接。

运行效果

image-20250125165710353

0

评论区