sed 命令用空白替换包括换行符模式的模式

sed 命令用空白替换包括换行符模式的模式

我有一个 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发现最后一行已经加载到缓冲区中,则终止脚本的进一步执行并打印缓冲区中存在的一行。

必须承认,sedFreeBSD 的行为有所不同,并且不显示最后一个奇数行。

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,可以在给定文件中进行就地编辑。

相关内容