趁着周末空隙把自己年久失修博客整理了一下,用到了 grep,xargs 和 sed 命令,使用这 3 个命令组合批量替换了所有 Markdown 文件中的图片链接。

我的博客从我的学生时代就开始了,不断折腾自己的博客,所以学会了 HTML/CSS/JS,下次和大家分享一下我的博客旅程。

这里不详细讲解这 3 个命令的使用,这 3 个命令的使用可以写出来厚厚的一本书。如果希望详细的了解这些命令,可以在 Linux 的终端下输入这样的命令查看文档,例如查看 grep 如何使用:

man grep

man 命令的常用操作:

  • 退出: 按 q 键
  • 查找:按 / 后输入查找关键字
  • 下一页: 按 ctrl + d 或者 ctrl + f,tips: 这里的 d 大概是 down,f 大概是 forward
  • 上一页: 按 ctrl + u 或者 ctrl + b,tips: 这里的 d 大概是 up,b 大概是 backward

查看其它命令的手册也是类似的。

我博客的问题

我的博客是用 hugo 构建的,所有的文章都放在 post 下面的目录里,图片则需要放在 static 的 images 下面,这样在用 vscode 写博客 Markdown 的时候无法在预览里面看到图片。于是我在 hugo 项目的根目录下添加了的一个 images 的符号链接到 static 目录下的 images, 才能解决图片预览的问题。

另外博客里面的图片越来越多也导致博客的 Git 仓库的体积越来越大,会导致上传下载都变得较慢,于是决定把博客里面的图片二进制文件单独放到一个 GitHub 仓库里面去,这个存放图片等二进制文件的仓库地址是 picb0,让博客仓库本身只保留一些主题文件和文章的 Markdown。

开始替换

grep

使用 grep 命令查找出所有包括图片的文件,并且显示将要被替换的文件内容

grep -nr '/images' .

其中:

  • -n: 表示查找文件的名字并且显示匹配的文件行号和内容
  • -r: 表示递归查找当前目录下的所有目录

输入结果是这样的:

sed

我常用的 sed 是这样替换文件内容,一般处理单个文件内容的替换,我会直接用 vim 来进行,替换的语法和 sed 也是差不多的。

sed -i 's/oldstr/newstr/g' filename

其中:

  • -i: 表示修改文件后保持到原文件名,并且创建一个 .bak 结尾的备份
  • oldstr:为需要被替换的字符串
  • newstr:为替换后的字符串

为了修改博客 Markdown 文件的图片链接,需要这样来修改

sed -i 's/\/images/https:\/\/raw.githubusercontent.com\/lewangdev\/picb0\/main\/oh-my-blog/g' 2013-03-04-so-load-path-in-linux.markdown

注意如果 oldstr 或者 newstr 中有 / 符号,需要进行转义为 \/, 所以这里:

  • oldstr
\/images
  • newstr
https:\/\/raw.githubusercontent.com\/lewangdev\/picb0\/main\/oh-my-blog

xargs

弄清楚 grep 和 sed 之后,在使用 xargs 和|(管道符)把这几个命令连起来

grep -rl  "oldstr" .| xargs sed -i 's/oldstr/newstr/g'
  • grep 的 n 参数换成了 l,因为我只需要文件名
  • xargs 命令可以使用分割标准输入的内容作为另外一个命令的参数

替换为我博客的实际需要替换的内容:

grep -rl  "/images" .| xargs sed -i 's/\/images/https:\/\/raw.githubusercontent.com\/lewangdev\/picb0\/main\/oh-my-blog/g'

使用 git log -p 查看一下是否替换成功

其它的替换方法

除了命令行,我们使用 ide 或者编辑器也很容易进行替换,比如 vscode 和 idea 系列的。

vscode

idea