HyperioN
HyperioN

Reputation: 3928

Remove every line before a string in file using Ansible

I have below file:

Scheduled jobs
Locale LANG set to the following: "en"
CONMAN:AWSBHU611W Conman could not initialize the HTTP or HTTPS connection.
Workstation Job Stream SchedTime Job State Pr Start Elapse ReturnCode Dependencies

HCPRODNWA #NW_HC_CA_BKP1 0106 02/13 **************************************** HOLD 10(02/13) (03:22)
NW_HC_CA_PREBKUP1B HOLD 10(02/13)(00:01)
NW_HC_CA_SANREPLICATION HOLD 10(02/13)(00:05)ΩNW_HC_CA_PREBKUP1B
NW_HC_CA_PPBACKUP HOLD 10(02/13)(03:17)
NW_HC_CA_SANREPLICATION
NW_HC_CA_GOLDCOPY HOLD 10(02/13)(00:01)
NW_HC_CA_SANREPLICATION

I want to remove all the lines before the line starting with 'Workstation Job...'

My ansible code is:

- name: Extract job details
  replace:
    path: /tmp/tws_jobs
    after: '(^Scheduled)'
    before: '(^Workstation)'
    regexp: '^(.*)$'
    replace: ''

But i'm not able to get the desired output. Instead i'm getting following message:

"msg": "Pattern for before/after params did not match the given file: (^Scheduled)(?P<subsection>.*?)(^Workstation)"

Upvotes: 2

Views: 4063

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 68189

    after: '(^Scheduled)'
    before: '(^Workstation)'

Q: "Pattern for before/after params did not match the given file"

Update (module replace explained)

Short answer: ^ and $ match the beginning and end of the file. Use \n to match the beginning and end of a line. The task below removes the lines between the lines after and before

    - replace:
        path: /tmp/tws_jobs
        regexp: '.*'
        replace: ''
        after: '^Scheduled.*?\n'
        before: '\nWorkstation.*?\n'

running in --check --diff gives

--- before: /tmp/tws_jobs
+++ after: /tmp/tws_jobs
@@ -1,6 +1,6 @@
 Scheduled jobs
-Locale LANG set to the following: "en"
-CONMAN:AWSBHU611W Conman could not initialize the HTTP or HTTPS connection.
+
+
 Workstation Job Stream SchedTime Job State Pr Start Elapse ReturnCode Dependencies

Details:

The content of the file is stored as a string

contents = to_text(f.read(), errors='surrogate_or_strict', encoding=encoding)

Given the file for testing

shell> cat /tmp/test.txt 
aaa
bbb
ccc
ddd
eee

Declare the default parameters to simplify testing

- hosts: localhost
  module_defaults:
    replace:
      path: /tmp/test.txt
      regexp: '.*'
      replace: ''
  tasks:
    - replace:
        ...
  1. Match the beginning of a file and line
  • ^a matches a at the beginning of the file
  • \n starts a new line
        after: '^a'
        before: '\nd'

gives

-aaa
-bbb
-ccc
+a
+
+
 ddd
 eee
  1. Match the rest of the line. In the previous example, the rest of the first line after a was removed. Match also the rest if you want to keep the whole line.

Make the '.' special character match any character at all, including a newline

  • Non-greedy ? match all characters .* till the new line \n
        after: '^a.*?\n'
        before: '\nd'

gives

 aaa
-bbb
-ccc
+
+
 ddd
 eee

Origin

A: Neither before nor after pattern matches any line in the file. Correct patterns should be

    after: '^Scheduled(.*)$'
    before: '^Workstation(.*)$'

But these patterns don't work either probably because of the open issues Replace module before/after still broken #47917.

It's possible to test the various patterns in a simplified example

shell> cat test.txt
aaa
bbb
ccc
ddd
eee

The task

   - replace:
        path: test.txt
        after: 'bbb'
        before: 'ddd'
        regexp: '^(.*)$'
        replace: ''

works as expected

shell> cat test.txt
aaa
bbb

ddd
eee

But neither

   - replace:
        path: test.txt
        after: '^bb'
        before: '^dd'
        regexp: '^(.*)$'
        replace: ''

nor

   - replace:
        path: test.txt
        after: '^bb(.*)$'
        before: '^dd(.*)$'
        regexp: '^(.*)$'
        replace: ''

change anything in the file

PLAY RECAP *************************************************************************
localhost: ok=1  changed=0  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0

[1] https://github.com/ansible/ansible/issues/47917#issuecomment-686339762

Upvotes: 3

Alex Sveshnikov
Alex Sveshnikov

Reputation: 4339

Try another approach: blockinfile:

- name: Extract job details
  blockinfile:
    marker_begin: '^Scheduled'
    marker_end: '^Workstation'

Upvotes: 0

Related Questions