How to get rid of special char '(u' - jinja2

I am using Salt with jinja2 "regex_search" and I try to extract some digits (release version) from the archive file name. Then use the value to create a symlink, that contains it. I've tried different combinations using "list", "join" and other filters to get rid of this Unicode char, but without success.
Example:
"release_info" variable gets value "release-name-0.2345.577_20190101_1030.tar.gz" and I need to get only digits between the dots.
Here is the corresponding part of the sls file:
symlink to current release {{ release_info }}:
file.symlink:
- name: /home/{{ component.software['component_name'] }}/latest
- target: /home/{{ component.software['component_name'] }}/{{ release_info |regex_search('(\d+\.\d+\.\d+)') }}
- user: support
- group: support`enter code here`
The expected result is "/home/support/0.2345.577", but I have "/home/support/(u'0.2345.577',)"
If I try to pipe "yaml" or "json" filter like:
{{ release_info |regex_search('(\d+\.\d+\.\d+)') | yaml }}
I've got:
/home/support/[0.2345.577]
which is not what I am looking for.
PS
I've got it, but seems to me as not a got approach. Just workaround.
{{ release_info |regex_search('(\d+\.\d+\.\d+)') |yaml |replace('[','') |replace(']','') }}

Hello Todor and Welcome to Stack Overflow!
I have tried the example that you have posted and here is how to achieve what you want
Note: I have changed the regex pattern a little in order to support any other possibilities that could have more digits e.g 0.1.2.3.4 and so on, but of course you can use your pattern as long as it works for you as expected.
Solution 1:
{{ release_info | regex_search("(\d(\.\d+){1,})") | first }}
The result before using first:
('0.2345.577', '.577')
The result after using first:
0.2345.577
Solution 2:
{{ release_info | regex_search("(\d\.\d+\.\d+)") | first }}
The result before using first:
('0.2345.577',)
The result after using first:
0.2345.577
first is a built-in filter in jinja that can return the first item in a sequence. you can check List of built-in filters for more information about the other filters

Related

dot liquid how to escape backslash

I am facing trouble in sending data from an azure web api having a legitimate backslash(\). Data field is user id which is of following pattern:
Domain\UserId
I want to store it in the database as it is. But Dot liquid doesn't process it.
I tried using escape, escape_once and replace
{{ body.requestor | escape_once }}
{{ body.requestor | escape }}
{{ body.requestor | replace "\", "\\"}}
but none of them worked. I cant ask caller of my web api to pass the user id with two backslashes - \\. I have to make a change in my web api to accept the user id's as they are.
Any inputs/pointers are appreciated.
Am I too late to the party? But here is the answer. First - Replace is case-sensitive. Then you need to use colon ":" fro parameters. And third, I have no explanation but I suspect that it takes item to find with escape and item to replace with, without escape. Here is the program
string templateString =
#"Nothing: '{{ k3 }}'
Replace with dash: '{{ k3|Replace:""\\"", ""-"" }}'
Replace with double slash: '{{ k3|Replace:""\\"", ""\\"" }}'";
Template.NamingConvention = new CSharpNamingConvention();
var t = Template.Parse(templateString);
string output = t.Render(Hash.FromDictionary(new Dictionary<string, object>() {{ "k3", "Domain\\user" } }));
Console.WriteLine(output);
Output:
Nothing: 'Domain\user'
Replace with dash: 'Domain-user'
Replace with double slash: 'Domain\\user'
This may be a bug in dot Liquid implementation of escape standard filter, or arguably a point where the Shopify specification is too vague hence implementations will differ. dot Liquid is using .NET RegEx replace causing "\" for pattern matching to be interpreted as the beginning of the pattern and an escape per https://learn.microsoft.com/en-us/dotnet/standard/base-types/character-escapes-in-regular-expressions
So you need {{ body.requestor | replace "\\", "\\"}}
(!)
The pattern to search for interprets the escape (so it's a single \ been matched) while the replacement string is not interpreting the escape (so it's the actual double \\ string).
This question appear when I'm looking for the same question, only for the ruby gem liquid implementation. David Burg's answer give me hint, and this is what works:
{{ "yes \ no" | replace "\", "\\\" }}
will replace the single backlash with double backlash
You nearly got it, the correct solution is:
{{ body.requestor | replace "\", "\\\\"}}
One backslash for the first argument and four for the 2nd.
The first argument is literal.
The 2nd argument gets parsed and because we want two backslashes we need to escape each one of them with another backslash. Making a total of four backslashes.

use variable from YFM in post

How can I use dynamic data file?
Say I have several data files: file1.yml, file2.yml, file3.yml and in YFM I want to tell which data file to use:
---
datafilename: file1
---
{{ site.data.datafilename.person.name }}
^
How to tell liquid that here should be file1
Ideally would be to use post's file name. So that post1.md would use post1.yml data file and so on.
This should work from inside a post :
{{ site.data[page.slug].person.name }}

Ansible - tilde as variable

I'm trying to put a tilde character in a variable that I'm going to use in a template in Ansible and for the life of me I cannot achieve what I want, as the tilde is being expanded in all sorts of weird ways.
What I want to achieve is to have some_var defined in my vars file so that I can use it in a template like so:
random_setting: "{{ some_var }}" and get this as a result: random_setting: ~, i.e. pure tilde, no quotes added.
Instead I keep getting this: random_setting: '~' (which is not acceptable for my use case) or this: random_setting: '' (which is just as bad).
My question is: how do I escape the tilde character, so that I can use it without it being either surrounded by quotes or expanded in some obscure way? I've already tried a few tricks including encoding the ~ character with base64 and using the | b64decode filter in Ansible, but nothing seems to work.
I think you might be confusing the real value with the output of Ansible.
If you run this:
---
- hosts: localhost
connection: local
vars:
var1: "~"
tasks:
- template: src=tilde-template.j2 dest=result.txt
with tilde-template.j2:
{{ var1 }}
And check the contents of result.txt it will contain just the tilde.

Ansible lookup a single line in a json file

I need to read an ip line from a dynamic generated json file and add it to a configuration file on the server.
At Ansible home page i found two modules which would help:
- lookup module
- fileinline module
The lookup examples however show looking up for the whole contents of a file using this phrase "{{ lookup('file', '/etc/foo.txt') }}"
How could i filter the result into reading a single line?
Does anybody know a good way to achieve this ?
You probably do want a special key from a JSON dict I guess? If it's just a random line which can not be accessed inside the JSON struct it will be hard. You would need to grep out the line in a separate task.
But let's assume you want a special value from a dict, then you can convert the JSON to an object with the from_json filter:
{{ lookup('file', '/etc/foo.txt') | from_json }}
Now if you want the value of bar from the contained data structure, something like this should work:
{{ (lookup('file', '/etc/foo.txt') | from_json).get('bar') }}

Certain Liquid filters does not perform filter function

I'm trying to use the handleize filter from liquid in Jekyll, but it seems to pass the text straight through without doing the filtering.
I have a include file (eg, _include/example.html) and inside there is
{{ 'Test Text' | handleize }}
From reading some documentation I expect the following text to be generated
test-text
but instead I get
Test Text
Is there something obvious I'm missing here? I'm using Jekyll 1.4.3 and liquid 2.5.5.
An interesting point is that there doesn't seem to be the handle filter when I look in the Liquid API docs, but confusingly the Jekyll docs points to the doc link given above.
Instead of rolling your own version of this filter, from Jekyll version 2.4.0 onward you can use the built-in slugify filter, which basically does what handleize did.
Handelize isn't implemented in Jekyll. See this issue here for an explanation (has to do with Jekyll-Liquid vs. Shopify-Liquid).
There are a couple Jekyll-Plugins you could use to add this functionality in. Or you could use the Downcase and Replace filters to do the job manually as needed:
{{ 'Test Text' | downcase | replace: ' ', '-' }}