Michal P.
Michal P.

Reputation: 55

Ansible - replace line in file

I'm really new to Ansible but I have a situation with replace module.

I tried my regex online https://regex101.com/ and it worked.

Then I tried the regex in my Ansible but it's not working. I also tried to use lineInFile module. Guess I'm somehow still thinking old way and not the right Ansible way. Therefore I'm not able to put this together.

- name: Update the CMakeLists, add -latomic
  replace:
    path: /home/{{ device_user }}/ros2_{{ ros2_distro }}/src/ros2/rcutils/CMakeLists.txt
    regexp: '^\s+target_link_libraries\(test_atomics_executable\s+\${PROJECT_NAME}'
    replace: '^\s+target_link_libraries\(test_atomics_executable\s+\${PROJECT_NAME} -latomic\)'

Those lines produces:

The error was: re.error: bad escape \s at position 1

I don't know why is that since the regex is ok, isn't it? I'm trying to find exact match I know that there is only one line such as this.

The CMakeLists.txt where I'm trying to do my changes:

  ...
  target_link_libraries(test_atomics_executable ${PROJECT_NAME})
  if(HAVE_LIBATOMICS)
    target_link_libraries(test_atomics_executable atomic)
  endif()
  add_test(NAME test_atomics COMMAND test_atomics_executable)
  ...

Could you please tell me what I doing wrong? (Please don't bother to just link the docs I have been already there and I tried to read it.)

Upvotes: 3

Views: 1784

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 67959

The error

 re.error: bad escape \s at position 1

points to the first position in the parameter replace

 replace: '^\s+target_link_libraries ... '

The parameter replace is not a regex. Try

- replace:
    path: CMakeLists.txt
    regexp: '^\s+target_link_libraries\(test_atomics_executable\s+\${PROJECT_NAME}\)(.*)$'
    replace: '  target_link_libraries(test_atomics_executable ${PROJECT_NAME} -latomic)'

This should replace the first line in the file

-  target_link_libraries(test_atomics_executable ${PROJECT_NAME})
+  target_link_libraries(test_atomics_executable ${PROJECT_NAME} -latomic)

Is this what you want? I'm not sure about the leading spacing.

Upvotes: 4

divij_o
divij_o

Reputation: 135

Like @Vladimir Botka pointed out in his answer, your regex expression needs to account for the ending parenthesis ) after \${PROJECT_NAME} and it also needs a $ at the end to assert the end of your exact match (you don't have to escape this ending $).

Also, if all occurrences of the line you want to replace are exactly target_link_libraries(test_atomics_executable ${PROJECT_NAME}), you don't need to quantify the space character (\s+). You can simply use:

regexp: '^target_link_libraries\(test_atomics_executable \${PROJECT_NAME}\)$'

or this (like @larsks pointed out), depending on if you still get an error while escaping ( and $ :

regexp: '^target_link_libraries\\(test_atomics_executable \\${PROJECT_NAME}\\)$'

Upvotes: 0

Related Questions