如何通过正则匹配Markdown标题拆分文件并以捕获组内容命名
通用拆分解决方案
直接用awk即可实现你的全部需求,流式处理大文件不会占用过高内存,适配绝大多数系统环境,不需要额外安装依赖。
针对你的示例场景的可直接运行命令
awk ' # 匹配块起始正则,捕获日期作为文件名 /^# 2020-[0-9]{2}-[0-9]{2}$/ { # 关闭上一个打开的输出文件,避免打开文件过多报错 if (output_file) close(output_file) # 提取捕获组内容拼接为输出文件名,substr($0,3)意为取当前行第3个字符之后的内容,也就是日期部分 filename = substr($0, 3) ".md" output_file = filename } # 只要存在有效的输出文件,就将当前行写入 output_file != "" { print > output_file } ' 你的源文件路径.txt
运行后会自动生成2020-01-01.md、2020-01-02.md两个文件,内容完全符合你的预期,同时会自动跳过开头不需要的# Title部分。
通用化调整方法
你可以根据自己的需求修改规则,适配不同的拆分场景:
- 调整块起始规则:修改第一行的正则匹配条件
/^# 2020-[0-9]{2}-[0-9]{2}$/为你需要的块起始正则即可 - 自定义文件名生成规则:修改
filename变量的赋值逻辑,比如要给文件名加前缀可以写成filename = "note_" substr($0,3) ".md",要修改后缀就把.md换成你需要的格式 - 自定义块结束边界:如果需要提前结束某个块的写入,只要加匹配结束标记的规则即可,例如遇到
--- 分隔符 ---就停止写入当前块:awk ' /^--- 分隔符 ---$/ { output_file = "" next } /你的块起始正则/ { if (output_file) close(output_file) # 自行调整文件名生成逻辑 filename = 你的文件名生成逻辑 output_file = filename } output_file != "" { print > output_file } ' 源文件路径.txt
如果是Linux系统自带的GNU awk,也可以用match的捕获组功能处理更复杂的文件名生成需求:
awk ' match($0, /^# (自定义前缀(2020-.*)自定义后缀)$/, m) { if (output_file) close(output_file) # m[1]对应第一个捕获组的内容,m[2]对应第二个捕获组,以此类推 filename = m[2] ".md" output_file = filename } output_file { print > output_file } ' 源文件.txt
优势说明
- 不需要编写复杂的多行匹配正则,awk天然按行流式处理,自动将两个块起始标记之间的所有内容归到前一个块,直到文件结束自动终止
- 直接使用正则捕获组内容生成文件名,不需要拆分后再批量重命名
- 大文件处理性能优异,不会一次性加载整个文件到内存,几十GB的文本文件也可以正常处理
内容的提问来源于stack exchange,提问作者Leeroy
相关产品推荐
相关产品推荐

