Replace last occurrence of .jar in ansible regex_replace

Viewed 858

How can I replace only the last character of .jar. Below is the sample value for LIST_jar[0].nameOfJar and the sample output expected

my-firsrt.jar-1.jar           >> my-firsrt.jar-1
my-firsrt-2.0.jar-1.jar       >> my-firsrt-2.0.jar-1
my-firsrt-1.0-jar-1.jar       >> my-firsrt-1.0-jar-1
my-firsrt-jar-1.0-jar-1.jar   >> my-firsrt-jar-1.0-jar-1
my-firsrt-jar-1.0.jar.jar     >> my-firsrt-jar-1.0.jar
my-firsrt-jar-1.0-jar.jar     >> my-firsrt-jar-1.0.jar

This is my sample code but it is not working accordingly as it is replacing all the jar value.

- name: Replace string
  copy:
    content: "{ name: jack }"
    dest: "{{ directory }}/JAR_LIST/{{ LIST_jar[0].nameOfJar | regex_replace('.jar') }}.log"
2 Answers

There are more options. The most simple is splitext. More versatile is split to manipulate multiple extensions. The filter regex_replace is more complex but universal.


splitext

Use splitext. For example

    - debug:
        msg: "dest: {{ (item|splitext).0 }}.log"
      loop: "{{ list_jar }}"

gives (given the list of filenames is in the variable list_jar)

  msg: 'dest: my-firsrt.jar-1.log'
  msg: 'dest: my-firsrt-2.0.jar-1.log'
  msg: 'dest: my-firsrt-1.0-jar-1.log'
  msg: 'dest: my-firsrt-jar-1.0-jar-1.log'
  msg: 'dest: my-firsrt-jar-1.0.jar.log'
  msg: 'dest: my-firsrt-jar-1.0-jar.log'

split

The next option is split. The task below gives the same results

    - debug:
        msg: "dest: {{ item.split('.')[:-1]|join() }}.log"
      loop: "{{ list_jar }}"

regex_replace

If you want to use regex_replace the tasks below give the same results. Either remove the extension and concatenate .log

    - debug:
        msg: "dest: {{ item|regex_replace('^(.*)\\.jar$', '\\1') }}.log"
      loop: "{{ list_jar }}"

, or replace the extension in the filter

    - debug:
        msg: "dest: {{ item|regex_replace('^(.*)\\.jar$', '\\1.log') }}"
      loop: "{{ list_jar }}"

To make the code more readable it's a good idea to put the regular expressions into the variables and use single-quoted style. For example

    - debug:
        msg: "dest: {{ item|regex_replace(my_regex, my_replace) }}"
      loop: "{{ list_jar }}"
      vars:
        my_regex: '^(.*)\.jar$'
        my_replace: '\1.log'

Below is my sample code but it is not working accordingly as it is replacing all the jar value.

Correct, because the . in regex means "any character." If you just want to replace the literal string .jar then don't use regex replace, just use replace() which will use the literal characters you provide to it.

Otherwise, if you wish to continue to use regex_replace, then quote that character and also specify that the pattern should only match the end of the string

- debug:
    msg: "{{ nameOfJar | regex_replace('[.]jar$', '') }}.log"
  vars:
    nameOfJar: my-firsrt-jar-1.0-jar-1.jar

We're going to assume the last two of your samples were just copy paste in this question, and that you prefer the .log outside the mustaches instead of just including '.log' in the replacement position of regex_replace

Related