技术解析

求批量替换的办法
0
2021-06-21 05:50:04
idczone

我想检索当前目录下所有*.MD 文件的内容,如果遇到

![text](url)

就替换为

{{< img src="url" alt="text">}}

//这里的 text 是指方括号里的任意文本,url 是指括弧里的任意链接地址,并非特指。

试了一个大佬提供的办法

sed -i -r 's/\!\[(.*)\]\((.*)\)/{{\2}}/' *.md

但是我这边报错

sed: 1: "s/\!\[(.*)\]\((.*)\)/{{ ...": \2 not defined in the RE

环境是 MacOS 系统,这要咋改?


你的行动并没有代表本来的意思,因为并不是所有的 ![]() 都是图,而且有些图是有 alt 的。最简单的正确做法是用 Markdown 编译器把 Markdown 编译成 Markdown。
当然,实际情况是你的所有 ![]() 都是图,那么这样的替换也是不安全的,因为你忘记了非贪婪匹配。
第一种解决方法是在 macOS 上安装 GNU sed,然后用 GNU sed。
第二种解决方法是在 macOS 上输入 man sed,查看 macOS 的 sed 如何在替换字符串里用捕获组。

simg src="\1" alt="\2">}}

这个正则太简单了,sed 命令 linux 支持,不知道 mac 是啥

-sh: syntax error near unexpected token `\(.*\)'
谢谢您的详细耐心解答,虽然没安装成 GNU SED,但至少明白问题出在哪儿了
兄嘚说的是,是我没搞明白

我运行是成功都 是不是 -i 错了?
$ echo '| sed -r 's/\!\[(.*)\]\((.*)\)/{{\2}}/'
src="text" alt="url">}}

我装了 gsed,然后用下面测试成功了。
gsed -i -r 's/\!\[(.*)\]\((.*)\)/{{\1}}/' *.md

我试了一下 你的命令没问题 我是在 windows 上的 wsl 上尝试的 修改文件成功了
我一开始 echo 然后 -i 结果报错和你一样
echo '| sed -i 's/\!\[(.*)\]\((.*)\)/{{\2}}/'
sed: -e expression char 49: invalid reference \2 on `s' command's RHS

simg src="\1" alt="\2">}}少复制了一个#


看看这个过程
```
$ cat Test.MD
![text](url)
![Pci1]( http://aa.bb.cc)
![DATA1]( http://aa.bb.cc)
![Pci2]( http://bbb.com)
![]
![DATA_2]( http://bbb.com)
![( http://)
![]
( http://)
![] (
http://)
$ sed -E 's/\!\[(.*)\]\((.*:\/\/.*)(.*)\)/{{img src="\1" alt="\2\3"}}/' Test.MD
![text](url)
{{img src="Pci1" alt="http://aa.bb.cc"}}
{{img src="DATA1" alt="https://aa.bb.cc"}}
{{img src="Pci2" alt="http://bbb.com"}}
![]
{{img src="DATA_2" alt="https://bbb.com"}}
![( http://)
![]
( http://)
![] (
http://)
```
这个例子里面稍微做了一点对 url 的检测,假设符合“*://*”的格式,也就是 http://*, https://* 或 ftp://*等等,这个可能是多余,或者说并不完备,只是个例子。

sed -i -r 'simg src="\1" alt="\2">}}test.md

牛!没想到正则还能这么玩。。。我 google 了一下:convert md to html,工具挺多的,应该能满足 lz 需求

在 Mac 下使用 sed 的 in-place replacement 要在 -i 后面加 一个额外的 '' 。这个跟 Linux 是不一样的。

问一下 lz 一个简单的问题 我今天有一个类似的需求。 有没有人帮忙解答一下
![text](url) --> ![text](../abcd/url) url 加一个前缀就可以了。需求很简单
http://url.html 不要匹配。url.html 匹配。 我只要要判断 \w 文本加一个 . 即可。可是 这个. 我总是无法匹配

$ echo '| sed -r 's/\]\((\w)/\]\(\.\.\/abcd\/\1/'
/>$ echo '| sed -r 's/\]\((\w)\./\]\(\.\.\/abcd\/\1/'
#![text](url.)

我 sb 了
\w 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。
我一直记成了 \w 是匹配完整的一个单词

echo 'http://url.com) | sed -r 's/\]\((\w*)([\.\/])/\]\(\.\.\/abcd\/\1\2/g'
http://url.com) />#

find . -type f -name "*.md" -exec perl -pi -e 's{} \;

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服