我有一个 yaml 文件,其中包含文本:
- name: flexvol-driver-host
hostPath:
type: DirectoryOrCreate
path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
imagePullSecrets:
- name: acrrepo-bad25ec678be80
我有一个 shell 脚本,我试图通过它- name:.*
删除imagePullSecrets:
仅有的。因此,如果imagePullSecrets:
那么- name:
它应该被移除并且只imagePullSecrets:
应该被保留。
请有人帮我用 sed 来做到这一点。
附:可以有多个条目imagePullSecrets:
在 yaml 文档中。所以所有imagePullSecrets:
应按上述相同方式处理。
答案1
如果指定的行接连不断,GNU sed 就可以这样做:
sed 'N;/\s*imagePullSecrets:\n[ -]*name:/!{P;D};s/\n.*//' file
编辑器缓冲区(模式空间)中始终有两行。如果它们与模式不匹配,则打印第一行,P
然后由命令删除D
,并将执行转移到脚本的最开始,即,下一行由命令添加到剩余的第二行N
,并再次循环检查是否与模式匹配。如果找到模式,则{P;D}
跳过命令,中断循环并s///
执行替换命令,它会切断缓冲区中的第二行。在下一步中,编辑器开始工作,将下一行加载到空缓冲区中,如果不是最后一行,则通过命令添加另一行N
。如果在执行命令时N
发现最后一行已经加载到缓冲区中,则终止脚本的进一步执行并打印缓冲区中存在的一行。
必须承认,sed
FreeBSD 的行为有所不同,并且不显示最后一个奇数行。
D
...删除模式空间中直到第一个换行符的文本,并使用生成的模式空间重新启动循环,而不读取新的输入行。
答案2
由于您的示例文档应该是一个 YAML 文件,我查找了一些与 Kubernetes 相关的其他 YAML 文件,看来您的文件实际上可能如下所示:
spec:
container:
- name: flexvol-driver-host
hostPath:
type: DirectoryOrCreate
path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
imagePullSecrets:
- name: acrrepo-bad25ec678be80
请注意,YAML 文件中的缩进很重要。
要删除此数据中每个部分的完整内容imagePullSecrets
,而不删除该部分本身,我们可以使用yq
(来自https://kislyuk.github.io/yq/)像这样:
$ yq -y '(.. | .imagePullSecrets? // empty) |= null' file.yml
spec:
container:
- name: flexvol-driver-host
hostPath:
type: DirectoryOrCreate
path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
imagePullSecrets: null
这会递归到文档的每个部分,拉出任何被调用的部分imagePullSecrets
并将其值设置为null
。这相当于清空该部分。
yq
与其--in-place
(或) 选项一起使用-i
,可以在给定文件中进行就地编辑。