文本替换

1
2
3
4
grep -zrolE 'cpu' # 通过-z可以匹配多行,通过-E可以匹配正则
sed '/requests:/{N;N;/requests:\n *memory/d}' org1-cli.tpl.bak > orgbak #grep通过N可以匹配到下一行的内容到模式空间
#上面的命令解读
首先 /requests 来匹配每一行,匹配到后,将其后三行读入模式空间,读入后一行一行继续匹配

sed 日记


由于项目的测试机器不能很好的满足k8s的requests资源要求,所以要将模板文件中的requests请求项注释掉,但是requests不仅仅有对CPU,memory的需求,也有对pv的要求,要注释的仅仅是CPU以及memory部分。

1
2
3
4
5
6
7
8
9
10
11
      requests:
storage: 10Mi
....
...
containers:
- name: cli
image:
resources:
requests:
memory: "0.2Gi"
cpu: "0.2"

需求是只注释如下三行,也即删除这三行

1
2
3
requests:
memory: "0.2Gi"
cpu: "0.2"

可以使用如下的替换命令

1
sed  '/requests/{N;N;s/requests:\n *memory: ".\+"/###/}' org1-cli.tpl >orgbak

由于要替换多个文件所以可以结合grep选择出要替换的文件

1
sed  '/requests/{N;N;s/requests:\n *memory: ".\+"/###/}' `grep -rl cpu`

总结


sed的命令也相当于一行的程序,sed对文本的处理是按照行来的,一行一行的处理,当/requests的时候,会匹配到有requests的行,此时模式空间中是带有 requests的 文本行,然后 N; N;会依次读入下一行,下一行到当前的模式空间中,然后之后的/s的匹配是针对现在的模式空间来匹配的,当通过 N; N;依次读入下一行,下下行的内容的时候,字符串之间是通过\n来链接的。比如对原文本,当通过N; N;读入后,模式空间中的内容将如下

1
requests: \n             memory: "0.2Gi"\n        cpu: "0.2"

后续的s/requests:\n *memory: “.+“/###/的匹配替换将是针对以上模式空间的内容来进行匹配的