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/*
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With