我的文件(values.yaml)中有以下内容:
global:
repo1:
enabled: true
repo2:
enabled: true
repo1:
replicaCount: 1
image:
tag: latest
pullPolicy: Always
repo2:
replicaCount: 1
image:
tag: latest
pullPolicy: Always
我想tag: latest
用类似的东西替换 for repo1 tag: newest1
,tag: latest
用类似的东西替换 for repo2 ,tag: newest2
这样我最终会得到:
global:
repo1:
enabled: true
repo2:
enabled: true
repo1:
replicaCount: 1
image:
tag: newest1
pullPolicy: Always
repo2:
replicaCount: 1
image:
tag: newest2
pullPolicy: Always
因此,我尝试搜索从文件repo1:\n replicaCount:1
到pullPolicy
文件末尾的范围,这样我得到的范围中只有一个标签,并且可以替换它。
我有
sed -i "" "N;/repo1:\n replicaCount:/,/pullPolicy/s/tag:.*/tag: newest1/g" values.yaml
然后几乎有效,但它总是删除最后pullPolicy
一行,例如:
global:
repo1:
enabled: true
repo2:
enabled: true
repo1:
replicaCount: 1
image:
tag: newest1
pullPolicy: Always
repo2:
replicaCount: 1
image:
tag: newest2
我使用的是 Mac,这就是为什么所有的双引号。
如何指定结束范围为文件末尾(我也尝试过$
但无济于事)或为 pullPolicy?
答案1
sed -z
使用空字符分隔符而不是换行符。
cat values.yaml | sed -z "s/\nrepo\([0-9]*\):\n\(\([^\n]\+\n\)*\)\([ \t]*\)tag:[^\n]*/\nrepo\1:\n\2\4tag: new\1/g"
做你想做的事。
\nrepo\([0-9]*\):\n
匹配以 开头的行repo
,并将其值记录在 中\1
。\(\([^\n]\+\n\)*\)
与任意数量的非空行(\+
至少一个字符)匹配,并将其值记录在\2
.\3
对于内部群体来说是浪费了。\([ \t]*\)tag:[^\n]*
tag
与包含带有空格缩进的单词的行匹配。\nrepo\1:\n\2\4
让第一行不变。tag: new\1
new
使用+ repo 值更改标签值。/g
用于通过单个命令完成这两项更改。
如果它不起作用,您可以尝试使用gnu-sed
(也可以安装在 MacOS 上)而不是默认的sed
.
答案2
sed -ri ':1;/^repo[12]/,/tag/!b;/tag/!{N;b1};s/^(repo(.).*)latest$/\1newest\2/'
不要忘记我用于调试的命令,它显示当前缓冲区中的内容。例如:
sed -nr ':1;/^repo[12]/,/tag/!b;/tag/!{N;b1};l;s/^(repo(.).*)latest$/\1newest\2/' file
repo1:\n replicaCount: 1\n image:\n tag: latest$
repo2:\n replicaCount: 1\n image:\n tag: latest$
生产:
sed -ri '/^repo[12]/!b;:1;/tag/!{N;b1};s/^(repo(.).*)latest$/\1newest\2/' file
答案3
使用python
编辑此文件的方式是导入 yaml 模块,然后将 yaml 文件加载到 python 字典(又名 hash | )中。关联数组,尽管是嵌套数组。
然后我们调整 yaml 文件中键的值。
最后我们将字典保存回 yaml 文件中。
sed 代码是在 yaml 文件的顶级节点上插入空行。
$ yaml_file='values.yaml'
$ python3 - "$yaml_file" <<\YAML
import sys, yaml
yaml_doc = sys.argv[1]
with open(yaml_doc) as fp:
h = yaml.safe_load(fp)
h['repo1']['image']['tag'] = 'newest1'
h['repo2']['image']['tag'] = 'newest2'
with open(yaml_doc, 'w') as fp:
yaml.safe_dump(h, fp, default_flow_style=False)
YAML
$ sed -Ei -e '1!{/^\S/{H;z;x;};}' "$yaml_file"