1

I have an Ansible yaml file that I want to append on a new line after state: present in the example matches below with use: package_manager using sed.

# Example 1 - name: Package X Install package: name: - package_1 - package_2 state: present # Example 2 - name: Package Y Install package: name: package_3 state: present # Example 3 - block: - name: Package Z Install package: name: package_4 state: present # etc. Further examples would be any combination, iteration of the above. 

However, there are multiple entries throughout the playbook that have a variable amount of preceding whitespace. The match needs to be directly under the state entry and have the same amount of indentation. I had trouble using state as a search anchor for sed as the Ansible playbook has other modules that use state: present.

The furthest I got was:

$ sed '/\s\{4,\}package:*\s\{6,\}state: present/a \s\{6,\}use: package_manager' 

As you can tell, it doesn't work at all. I'm lost; any help would be appreciate!

1
  • Unless you are in a very specific situation, package should detect the package manager to use by itself. The use option is more for debug/tests purpose than for production use. It would be better to fix the problem preventing the auto detection from gathered facts rather than patching your tasks at wild. In other words, double check you're not in an X/Y problem Commented Mar 28, 2021 at 22:43

2 Answers 2

2

I think you can capture the spaces from the matched line and then substitute while inserting

sed 's/^\( *\)state: present$/&\n\1use: package_manager/' ansible.yaml 

Output:

# Example 1 - name: Package X Install package: name: - package_1 - package_2 state: present use: package_manager # Example 2 - name: Package Y Install package: name: package_3 state: present use: package_manager # Example 3 - block: - name: Package Z Install package: name: package_4 state: present use: package_manager # etc. Further examples would be any combination, iteration of the above. 
1
  • Thanks. But the problem is I can't use state: present as the search anchor because other modules outside of package use it. Commented Mar 4, 2021 at 22:20
0

Using a proper YAML parser on the data in the question,

$ yq -y '(.. | .package? | select(.state == "present")) |= (.use = "package_manager")' file.yml - name: Package X Install package: name: - package_1 - package_2 state: present use: package_manager - name: Package Y Install package: name: package_3 state: present use: package_manager - block: - name: Package Z Install package: name: package_4 state: present use: package_manager 

This uses the yq parser to add the use: package_manager key+value in each package section that contains a state key corresponding to the value present.

It does this by recursing over all the data, picking out the package sections that have a state key with the value present. It then adds the new key and value to those sections.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.