使用 sed 匹配动态多行字符串并附加到它

使用 sed 匹配动态多行字符串并附加到它

我有一个 Ansible yaml 文件,我想state: present在下面的示例中与use: package_managerusing匹配后在新行中附加该文件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.

但是,整个剧本中有多个条目的前面的空格数量不同。匹配项必须位于state条目的正下方,并且具有相同的缩进量。我state在使用 的搜索锚点时遇到了麻烦,sed因为 Ansible playbook 还有其他使用state: present.

我得到的最远的是:

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

正如你所知,它根本不起作用。我迷路了;任何帮助将不胜感激!

答案1

我认为你可以捕获匹配行中的空格,然后在插入时进行替换

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

输出:

# 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.

答案2

对问题中的数据使用适当的 YAML 解析器,

$ 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

这使用解析器yq在包含与 value 对应的 key的每个部分中添加use: package_managerkey+value 。packagestatepresent

它通过递归所有数据,选出键值为 的package部分来实现此目的。然后它将新的键和值添加到这些部分。statepresent

相关内容