shell脚本:循环获取.md文件,并替换markdown元数据字符md-metadata-replacer.sh

  1. 不设置条件全局替换
  2. 设置条件,只匹配第一个—-开头到—-结束范围

不设置条件全局替换

#!/bin/bash

# 获取当前目录以及所有子目录下的.md文件路径
file_list=$(find . -type f -name "*.md")

# 遍历所有.md文件,去掉"- '['"开头的"]'"结束中间的引号,并替换中间的'|'为','
while IFS= read -r file_path; do
  sed -i -e "s/- '\[\(.*\)|\(.*\)\]'/- [\1,\2]/g" \
         -e "s/'//g" \
         -e "s/|/,/g" "$file_path"
done <<< "$file_list"

设置条件,只匹配第一个—-开头到—-结束范围

#!/bin/bash

# 获取当前目录以及所有子目录下的.md文件路径
file_list=$(find . -type f -name "*.md")

# 遍历所有.md文件,替换第一个符合条件的区间内的内容
while IFS= read -r file_path; do
  # 获取第一个以'---'开始和结束的区间的行号
  start_line=$(grep -n "^---$" "$file_path" | head -n 1 | cut -d ':' -f 1)
  end_line=$(grep -n "^---$" "$file_path" | head -n 2 | tail -n 1 | cut -d ':' -f 1)

  # 替换该区间内的内容
  sed -i "${start_line},${end_line} {s/- '\[\(.*\)|\(.*\)\]'/- [\1,\2]/g; s/'//g; s/|/,/g}" "$file_path"
done <<< "$file_list"

GPT解释:

这个脚本是一个 bash 脚本。主要用途是遍历当前目录及其所有子目录下的所有以 .md 结尾的文件,并对每个文件进行操作。

首先,通过 find 命令获取所有以 .md 结尾的文件路径,存放在 file_list 变量中。


然后,使用 while 循环,逐一读取 file_list 中的文件路径。对于每个文件,获取该文件中第一个以 '---' 开始和结束的区间的行号,并记录为 start_line 和 end_line 变量。接着,使用 sed 命令对该区间内的内容进行替换,具体地,将形如 - '[xxx|yyy]' 的内容替换成 [- xxx,yyy] 的形式,同时去掉引号和竖线。


最后,将替换后的内容写回到原文件中,完成对该文件的修改。


需要注意的是,如果文件中存在多个符合条件的区间,本脚本只会替换第一个区间内的内容。

sh2.png

上面的代码发现会把其他’’空值的引号也去掉,改进为

#!/bin/bash

# 获取当前目录以及所有子目录下的.md文件路径
file_list=$(find . -type f -name "*.md")

# 遍历所有.md文件,替换第一个符合条件的区间内的内容
while IFS= read -r file_path; do
  # 获取第一个以'---'开始和结束的区间的行号
  start_line=$(awk '/---/{print NR;exit}' "$file_path")
  end_line=$(awk '/---/{print NR}' "$file_path" | sed -n '2p')

  # 替换该区间内的内容
  sed -i "${start_line},${end_line} s/- '\[\(.*\)\]'/- [\1]/g; ${start_line},${end_line} s/\//,/g" "$file_path"
done <<< "$file_list"

改进,增加判断

#!/bin/bash
echo "当前路径"
pwd
echo "开始脚本"
# 获取当前目录以及所有子目录下的.md文件路径
file_list=$(find /home/runner/work/elog-notion-hexo/elog-notion-hexo/download/ -type f -name "*.md")

# 如果没有找到任何.md文件,就输出一条消息并退出脚本
if [ -z "$file_list" ]; then
  echo "没有找到任何.md文件"
  exit 0
fi

# 遍历所有.md文件,替换第一个符合条件的区间内的内容
while IFS= read -r file_path; do
  # 获取第一个以'---'开始和结束的区间的行号
  start_line=$(awk '/---/{print NR;exit}' "$file_path")
  end_line=$(awk '/---/{print NR}' "$file_path" | sed -n '2p')

  # 如果 start_line 或 end_line 为空,就跳过这个文件
  if [ -z "$start_line" ] || [ -z "$end_line" ]; then
    echo "跳过文件 $file_path,因为无法确定要替换的行范围"
    continue
  fi

    # 输出已经被修改的文件名
  echo "已经修改文件:$file_path"

  # 替换该区间内的内容
  sed -i "${start_line},${end_line} s/- '\[\(.*\)\]'/- [\1]/g; ${start_line},${end_line} s/\//,/g" "$file_path"
done <<< "$file_list"

如果用在Github Actions上,则

#!/bin/bash
echo "当前路径"
pwd
echo "开始脚本"
# 获取当前目录以及所有子目录下的.md文件路径
file_list=$(find /home/runner/work/elog-notion-hexo/elog-notion-hexo/download/ -type f -name "*.md")

# 如果没有找到任何.md文件,就输出一条消息并退出脚本
if [ -z "$file_list" ]; then
  echo "错误:没有找到任何.md文件"
  exit 1
fi

# 遍历所有.md文件,替换第一个符合条件的区间内的内容
while IFS= read -r file_path; do
  # 获取第一个以'---'开始和结束的区间的行号
  start_line=$(awk '/---/{print NR;exit}' "$file_path")
  end_line=$(awk '/---/{print NR}' "$file_path" | sed -n '2p')

  # 如果 start_line 或 end_line 为空,就跳过这个文件
  if [ -z "$start_line" ] || [ -z "$end_line" ]; then
    echo "跳过文件 $file_path,因为无法确定要替换的行范围"
    continue
  fi

    # 输出已经被修改的文件名
  echo "已经修改文件:$file_path"

  # 替换该区间内的内容
  sed -i "${start_line},${end_line} s/- '\[\(.*\)\]'/- [\1]/g; ${start_line},${end_line} s/\//,/g" "$file_path"
done <<< "$file_list"

欢迎指出任何有错误或不够清晰的表达,可以在下面评论区评论。

×

喜欢就点赞,疼爱就打赏

//