0

I have a yaml file which include text:

 - name: flexvol-driver-host
          hostPath:
            type: DirectoryOrCreate
            path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
     imagePullSecrets:
     -   name: acrrepo-bad25ec678be80

I have a shell script through which I am trying to remove - name:.* for imagePullSecrets: only. So If imagePullSecrets: have - name: below it then it should be removed and only imagePullSecrets: should be preserved.

Please can someone help me to do this with sed.

PS: There can be more than one entry of imagePullSecrets: in yaml doc. So all imagePullSecrets: should be handled in same way as mentioned above.

4
  • sed is not good at processing multi-line input or structured text like yaml. Use a YAML parser. There are many to choose from, including command-line tools like yq. Most languages have decent yaml parser libraries - e.g. perl's YAML and python's pyyaml
    – cas
    Commented Dec 7, 2021 at 9:47
  • Your YAML document seems to be mis-formatted (the second line has too much indentation). Could you please double check the formatting and make sure it's valid YAML? This matters since you want to delete a particular "path" in the document's structure. This task is trivial to solve with common command-line YAML parsing tools. Line-oriented text-editing tools like sed are not generally suitable for manipulating structured document formats.
    – Kusalananda
    Commented Dec 7, 2021 at 11:31
  • It is unclear whether you want to remove only the first entry from the imagePullSecrets array, or whether you want to remove all entries if there are more than one (basically setting the array to null). It is further unclear whether there are more imagePullSecrets arrays in the file that should be handled in the same way.
    – Kusalananda
    Commented Dec 7, 2021 at 12:18
  • @they: I have edited the que. There can be multiple entries of imagePullSecrets:
    – Thor
    Commented Dec 7, 2021 at 17:29

2 Answers 2

0

GNU sed can do so if the specified lines follow one after another:

sed 'N;/\s*imagePullSecrets:\n[ -]*name:/!{P;D};s/\n.*//' file

There are always two lines in the editor buffer (pattern space). If they do not match the pattern, then the first line is printed by P then deleted by the D command and the execution is transferred to the very beginning of the script, i.e. the next line is added to the remaining second line by the N command and again in cycle checked for a match with the pattern. If the pattern is found, then the {P;D} commands are skipped, the cycle is interrupted and the substitution command s/// is executed, it cuts off the second line in the buffer. In the next step, the editor begins to work by loading the next line in empty buffer and if it is not the last one, adds another line by the N command. If at the moment of execution of the N command, it turns out that the last line has already been loaded into the buffer, then the further execution of the script is terminated and one line existing in the buffer is printed.

It must be admitted that sed from FreeBSD behaves differently and does not display the last odd line.

D ...delete text in the pattern space up to the first newline, and restart cycle with the resultant pattern space, without reading a new line of input.

0

As you example document is supposed to be a YAML file, I looked up some other YAML files related to Kubernetes, it appears your file might actually look something like the following:

spec:
  container:
    - name: flexvol-driver-host
      hostPath:
        type: DirectoryOrCreate
        path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
  imagePullSecrets:
    - name: acrrepo-bad25ec678be80

Note that indentation in YAML files is important.

To delete the full contents of each imagePullSecrets section in this data, without removing the section itself, we might use yq (from https://kislyuk.github.io/yq/) like so:

$ 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

This recurses into each part of the document, pulling out any section that is called imagePullSecrets and sets its value to null. This is equivalent of emptying the section.

Use yq with its --in-place (or -i) option to make an in-place edit in the given file.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .