Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible roles: change file extension

Tags:

ansible

In a Vagrant setup, I use Ansible to provision the virtual machine.

In one of the Ansible roles, I have a task that copies some files inside ~/bin/ folder:

~/bin/one.sh
~/bin/two.sh

I want to create symlinks of those files so the end result looks like:

~/bin/one.sh
~/bin/two.sh
~/bin/one (symlink to ~/bin/one.sh)
~/bin/two (symlink to ~/bin/two.sh)

How can I achieve that? So far I have tried this but it doesn't work:

- name: Common tasks =>Create symlinks for utilities
  file: src=~/bin/{{ item }} dest=~/bin/  mode=755 state=link
  with_fileglob:
    - bin/*

I need to put a regex inside dest=~/bin/ that takes the file name (like one.sh) and removes the extension (one.sh becomes one) but I'm not sure how to do it.

Update

I finally used this tasks:

- name: Copy common files to ~/bin
  copy: src={{ item }} dest=~/bin/  mode=755
  with_fileglob:
    - bin/*

- name: Ensure symlinks for utilities exist
  file: src=~/bin/{{ item | basename | regex_replace('(\w+(?:\.\w+)*$)', '\1') }} dest=~/bin/{{ item | basename | regex_replace('\.sh','') }} mode=755 state=link
  with_fileglob:
    - bin/*
like image 504
numediaweb Avatar asked Dec 02 '22 13:12

numediaweb


2 Answers

From other useful filters chapter:

To get the root and extension of a path or filename (new in version 2.0):

# with path == 'nginx.conf' the return would be ('nginx', '.conf')
{{ path | splitext }}

You need to reference the first element of the list, so:

- name: Common tasks => Ensure symlinks for utilities exist
  file: src=~/bin/{{ item }} dest=~/bin/{{ (item | splitext)[0] }} mode=755 state=link
  with_fileglob:
    - bin/*

Of course, the above task works given the provisions specified in the task which you later edited out of the question, because fileglob lookup is running locally on the control machine (and in the previous task you used to copy the same files, so this one assumes they exist on local machine).

If you want to run the task singlehandedly you'd have first to prepare a list of the files on the target node with the find module and then running the above looping over the results.

like image 136
techraf Avatar answered Jan 20 '23 22:01

techraf


I am using the following expression to change filename e.g. from test.file.name.txt to test.file.name.csv

"{{ ((item| splitext)[:-1] | join('.')) }}.csv"

This will split the item on any dot, cut the latest off and join all together again with a dot. After this you cann add the extension of your favour.

like image 25
fty4 Avatar answered Jan 20 '23 21:01

fty4