# Remove multiple lines of text from a JS file

**URL:** <https://forum.ansible.com/t/remove-multiple-lines-of-text-from-a-js-file/43622>\
**Category:** Get Help\
**Tags:** task\
**Created:** [June 28, 2025, 9:32pm UTC](https://forum.ansible.com/t/remove-multiple-lines-of-text-from-a-js-file/43622 "2025-06-28T21:32:33Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![RRohi](https://avatars.discourse-cdn.com/v4/letter/r/f19dbf/32.png) [@RRohi](https://forum.ansible.com/u/RRohi)\
**Post date:** [June 28, 2025, 9:32pm UTC](https://forum.ansible.com/t/remove-multiple-lines-of-text-from-a-js-file/43622/1 "2025-06-28T21:32:33Z")

</div>

Hello

I’m struggling to find a solution to removing multiple lines from a js file thousands of rows long.  
I can’t use markers for blockinfile since after a version update, the function may be somewhere else and the markers will be gone then and I can’t use a fixed position either, since this could also change then.

I have tried lineinfile and replace modules and the regex that would work in [regex101.com](http://regex101.com) in Python flavor will either error out or show it’s already ok, nothing was changed.

I have tried complex patterns to make absolutely sure I won’t delete anything by accident, but I’m at the moment at this very simple, yet more dangerous pattern and Ansible says it’s already ok.

```yml
- name: Remove the subscription box from the Datacenter Summary page.
  ansible.builtin.lineinfile:
    path: /root/test.js
    regexp: '^\s+?{\n\s+title: gettext\(''Subscriptions''\),.*(\n.+){17}'
    state: absent

```

A more strict, but more complex pattern that matches every line in the block was:

```regex
^\s+?{\n\s+?title: gettext\(''Subscriptions''\),\n(\s+?(height|items).+?\n){2}\s+?{\n(\s+?(xtype|itemId|userCls|listeners|element|click).+?\n){6}\s+?if\s\(.+?\n\s+?window\.open.+?\n\s+?}\n.+?\n(\s+?},\n){2}\s+?],\n\s+?},

```

Wrapped regex around double quotes instead of single quotes and the pattern would look like this, but it still says everything is ok:

```regex
^\\s+?{\\n\\s+?title: gettext\\('Subscriptions'\\),\\n(\\s+?(height|items).+?\\n){2}\\s+?{\\n(\\s+?(xtype|itemId|userCls|listeners|element|click).+?\\n){6}\\s+?if\\s\\(.+?\\n\\s+?window\\.open.+?\\n\\s+?}\\n.+?\\n(\\s+?},\\n){2}\\s+?],\\n\\s+?},

```

Is there even a way to do this with Ansible natively?

Basically I’m trying to remove the following lines from pvemanagerlib.js.

```js
    {
        title: gettext('Subscriptions'),
        height: 220,
        items: [
        {
            xtype: 'pveHealthWidget',
            itemId: 'subscriptions',
            userCls: 'pointer',
            listeners: {
            element: 'el',
            click: function() {
                if (this.component.userCls === 'pointer') {
                window.open('https://www.proxmox.com/en/proxmox-virtual-environment/pricing', '_blank');
                }
            },
            },
        },
        ],
    },

```

Don’t panic, I’m running Proxmox at home and their subscription is way too expensive for what I do with it and I started using it last month. I want to clean up the Datacenter Summary page.

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [June 29, 2025, 6:05pm UTC](https://forum.ansible.com/t/remove-multiple-lines-of-text-from-a-js-file/43622/2 "2025-06-29T18:05:37Z")

</div>

Create block marks first. For example, given the file _/tmp/pvemanagerlib.js_ for testing

```auto
    {
        title: gettext('foo'),
        height: 220,
        items: [
        ],
    },
    {
        title: gettext('Subscriptions'),
        height: 220,
        items: [
        ],
    },
    {
        title: gettext('bar'),
        height: 220,
        items: [
        ],
    },

```

The play

```yaml
- hosts: localhost

  tasks:

    - name: Create block markers.
      vars:
        marker: Subscriptions
        regex1: |-
          (\s*)title: gettext\('Subscriptions'\),
        replace1: |-
          \1title: gettext('Subscriptions'),
        regex2: ' },'
      block:

        - name: Create begin marker.
          ansible.builtin.replace:
            path: /tmp/pvemanagerlib.js
            regexp: "{{ regex1 }}"
            replace: |-

              {{ '#' }} BEGIN ANSIBLE MANAGED BLOCK {{ marker }}{{ replace1 }}

        - name: Create end marker
          ansible.builtin.replace:
            path: /tmp/pvemanagerlib.js
            regexp: ({{ regex1 }}[\s\S]*?{{ regex2 }})
            replace: |-
              \1
              {{ '#' }} END ANSIBLE MANAGED BLOCK {{ marker }}

```

gives

```auto
    {
        title: gettext('foo'),
        height: 220,
        items: [
        ],
    },
    {
# BEGIN ANSIBLE MANAGED BLOCK Subscriptions
        title: gettext('Subscriptions'),
        height: 220,
        items: [
        ],
    },
# END ANSIBLE MANAGED BLOCK Subscriptions
    {
        title: gettext('bar'),
        height: 220,
        items: [
        ],
    },

```

Then, the editing is trivial. The play is not idempotent.

---

<div class="post-metadata">

**Author:** ![RRohi](https://avatars.discourse-cdn.com/v4/letter/r/f19dbf/32.png) [@RRohi](https://forum.ansible.com/u/RRohi)\
**Post date:** [June 29, 2025, 8:29pm UTC](https://forum.ansible.com/t/remove-multiple-lines-of-text-from-a-js-file/43622/3 "2025-06-29T20:29:25Z")

</div>

First off, thanks a ton! Not only I got what I wanted I accidentally found out why my regex patterns didn’t work. I had no idea you had to enclose them in brackets (groups).

I had to play with it and change it to include the starting `{`, so the result would be:

```yml
# BEGIN ANSIBLE MANAGED BLOCK Subscriptions
    {
        title: gettext('Subscriptions'),
        height: 220,
        items: [
        ],
    },
# END ANSIBLE MANAGED BLOCK Subscriptions

```

instead of

```yml
    {
# BEGIN ANSIBLE MANAGED BLOCK Subscriptions
        title: gettext('Subscriptions'),
        height: 220,
        items: [
        ],
    },
# END ANSIBLE MANAGED BLOCK Subscriptions

```

Here are my tasks. I broke them up into individual tasks because `ansible-lint` complained something about having to use `when:` somewhere in or before the blocks and I didn’t feel like troubleshooting it.

```yml
- name: Find the BEGIN marker.
  ansible.builtin.find:
    name: /root
    patterns: 'test.js'
    file_type: file
    use_regex: true
    read_whole_file: true
    contains: "BEGIN ANSIBLE MANAGED BLOCK {{ regex_marker }}"
  register: blockcheck
  changed_when: false

- name: Create the BEGIN marker.
  ansible.builtin.replace:
    path: /root/test.js
    regexp: "{{ regex_begin_find }}"
    replace: |
      \n{{ '#' }} BEGIN ANSIBLE MANAGED BLOCK {{ regex_marker }}{{ regex_begin_replace }}
  when: blockcheck.matched == 0

- name: Create the END marker.
  ansible.builtin.replace:
    path: /root/test.js
    regexp: ({{ regex_end_blockstart }}[\s\S]*?{{ regex_end_blockend }})
    replace: |
      \1{{ '#' }} END ANSIBLE MANAGED BLOCK {{ regex_marker }}
  when: blockcheck.matched == 0

```

EDIT: Since this action is not idempotent, I added a check.

The host `host_vars` file contains the following patterns:

```regex
regex_begin_find: |
  (\s+?{\n)(?:\s+?title: gettext\('Subscriptions'\),)
regex_begin_replace: |
  \1\ttitle: gettext('Subscriptions'),
regex_end_blockend: |
  (\s+?],\n\s+?},)
regex_end_blockstart: |
  ((\s+?)title: gettext\('Subscriptions'\),)
regex_marker: Subscription

```

Outcome:

```js
    {
        itemId: 'nodeview',
        xtype: 'pveDcNodeView',
        height: 250,
    },
# BEGIN ANSIBLE MANAGED BLOCK Subscription
    {
        title: gettext('Subscriptions'),
        height: 220,
        items: [
        {
            xtype: 'pveHealthWidget',
            itemId: 'subscriptions',
            userCls: 'pointer',
            listeners: {
            element: 'el',
            click: function() {
                if (this.component.userCls === 'pointer') {
                window.open('https://www.proxmox.com/en/proxmox-virtual-environment/pricing', '_blank');
                }
            },
            },
        },
        ],
    },
# END ANSIBLE MANAGED BLOCK Subscription
    ],

    listeners: {
    resize: function(panel) {
        Proxmox.Utils.updateColumns(panel);
    },
    },

```

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [June 29, 2025, 9:39pm UTC](https://forum.ansible.com/t/remove-multiple-lines-of-text-from-a-js-file/43622/4 "2025-06-29T21:39:05Z")

</div>

Nice! You can create 2nd capturing group and avoid the hard-coded TAB

```yaml
regex_begin_find: |
  (\s+?{\n)(\s+)title: gettext\('Subscriptions'\),
regex_begin_replace: |
  \1\2title: gettext('Subscriptions'),

```

---

<div class="post-metadata">

**Author:** ![RRohi](https://avatars.discourse-cdn.com/v4/letter/r/f19dbf/32.png) [@RRohi](https://forum.ansible.com/u/RRohi)\
**Post date:** [June 29, 2025, 9:50pm UTC](https://forum.ansible.com/t/remove-multiple-lines-of-text-from-a-js-file/43622/5 "2025-06-29T21:50:08Z")

</div>

When I try that, Python complains that I’m trying to reference an invalid group.

Changed it back and it worked again.

I think it’s fine, the last task (not included in this thread) is going to delete the whole block anyway.

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [June 29, 2025, 9:53pm UTC](https://forum.ansible.com/t/remove-multiple-lines-of-text-from-a-js-file/43622/6 "2025-06-29T21:53:06Z")

</div>

Wild guess, have you deleted the closing parenthesis ) ? (in the end of the line)

---

<div class="post-metadata">

**Author:** ![RRohi](https://avatars.discourse-cdn.com/v4/letter/r/f19dbf/32.png) [@RRohi](https://forum.ansible.com/u/RRohi)\
**Post date:** [June 29, 2025, 11:02pm UTC](https://forum.ansible.com/t/remove-multiple-lines-of-text-from-a-js-file/43622/7 "2025-06-29T23:02:13Z")

</div>

I accidentally deleted the whole playbook 🤬.  
All I have of it is what I copied here. 😖

EDIT: That was too close. I was able to restore the last state from the VS Code cache.

* * *

Regarding your last question. I now see that you have slightly changed the find pattern. I just changed `\t` to `\2` in replace. I’ll try it in the evening.

---

<div class="post-metadata">

**Author:** ![RRohi](https://avatars.discourse-cdn.com/v4/letter/r/f19dbf/32.png) [@RRohi](https://forum.ansible.com/u/RRohi)\
**Post date:** [July 2, 2025, 3:19pm UTC](https://forum.ansible.com/t/remove-multiple-lines-of-text-from-a-js-file/43622/8 "2025-07-02T15:19:37Z")

</div>

Thanks. As suspected, I changed my `regex_begin_find` pattern and it worked. 👍

* * *

oooh, I see. Each capturing group is represented with a numbered backslash in the replace part, unless the groups are named. Good to know.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [August 1, 2025, 3:19pm UTC](https://forum.ansible.com/t/remove-multiple-lines-of-text-from-a-js-file/43622/9 "2025-08-01T15:19:48Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
