我有一个包含许多不同标题的 Markdown 文件,我正在编写一个 CI 脚本,每次推送到存储库时都会修改其中一个部分。我的README.md如下,
自述文件.md
# Title
....some text...
## Heading 1
...some text...
## Heading 2
...some text....
## Structure
<pre>
┬
├ first-dir
┬ first-sub-dir
├ second-dir
┬ second-sub-dir-1
├ second-sub-dir-2
</pre>
## Heading 3
...some text....
我想使用 sed修改Structure
命令输出的部分。tree -d -L 2 -n
我尝试使用
var=$(tree -d -L 2 -n)
sed -i -E "s/## Structure\n<pre>\n(.|\n)*?<\/pre>/## Structure\n<pre>\n ${var} \n<\/pre>/g" README.md
但它不能正常工作。我读到了有关命令替换的内容,sed
但我无法正确理解它。与此有关的任何帮助sed
或awk
将是有益的。
答案1
awk '
/^<\/pre>$/ {flag=0}
/^## Structure$/ {print; getline; print
system("tree -d -L 2 -n")
flag=1}
!flag' <<<$(<file) >file
<<<$(<file) >file
- 一种自定义缓冲区(不适用于所有 shell)。可以用临时文件替换:file >tmp
更复杂的方式,我举个例子:
sed -i '/^## Structure/!b
N;h
:1;N
/<\/pre>$/!b1
s/.*\n//
x;p
s/.*/tree -d -L 2 -n/e
G' file
/^## Structure/!b
- 脚本将忽略所有与模式不匹配的行。并且显示不变。一旦遇到模式,以下脚本就会开始运行。
N
- 将下一行输入附加到模式空间(工作缓冲区)。结果,我们有 - ## Structure\n<pre>
h
- 将模式空间复制到保存空间(备用缓冲区)。
:1
- 为跳跃做一个标记。
N
- 追加下一行。我们进入工作缓冲区 - ## Structure\n<pre>\n┬
/<\/pre>$/!b1
- 如果工作缓冲区中的行尾与模式不匹配,那么我们返回标签:1
并每次循环添加下一行,直到</pre>
添加行为止。
s/.*\n//
- 然后我们删除工作缓冲区中除最后一行之外的所有内容</pre>
。
x
- 我们更改缓冲区的内容,以便该行出现在工作缓冲区中 - ## Structure\n<pre>
。而在备用缓冲区中有一行——</pre>
p
打印工作缓冲区的内容## Structure\n<pre>
s/.*/tree -d -L 2 -n/e
——我们用shell命令替换缓冲区的内容并执行它。 - 将备用缓冲区的
G
内容附加到工作缓冲区 - 附加到输出 shell 命令。</pre>
内容被打印并且作业返回到脚本的开头。之后的下一行</pre>
被读入工作缓冲区。并且由于文件中不再有与模式匹配的行/^## Structure/!b
,因此剩余的行也将像第一行一样显示不变。