refriedjello
refriedjello

Reputation: 817

Ansible Jinja template - read file line by line

I am trying to parse a text file line by line inside of a for loop. I can parse JSON data fine, but a seemingly simpler task is failing here. It appears Jinja is not delineating based on line-feeds.

In my YAML playbook I have declared the source file and lookup (query) function:

vars:
    myfile: /some/text/file.txt
    myfile_list: "{{ query('file', myfile) }}"

The source file 'myfile' is simply a list of IPs in CIDR format:

1.2.3.4/32
5.6.7.8/32
10.20.30.0/24

In the Jinja2 template file I am running a for loop:

{% for line in myfile_list %}
permit ip {{ line }} any
{% endfor %}

The desired output is:

permit ip 1.2.3.4/32 any
permit ip 5.6.7.8/32 any
permit ip 10.20.30.0/24 any

Instead I get this:

permit ip 1.2.3.4/32
5.6.7.8/32
10.20.30.0/24 any

I have tried the lookup plugin instead. Setting 'wantlist=True'. Following the lookup call using the list filter. I either get one character per line, or a single blob of text as shown above. If I run the Linux shell command 'file' against my source file it's seen as "ASCII text".

Upvotes: 2

Views: 7846

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 68104

Q: "Read file line by line"

A: It's possible to read the whole file only and split the lines

myfile_list: "{{ lookup('file', myfile).splitlines() }}"

Upvotes: 3

Zeitounator
Zeitounator

Reputation: 44675

The lookup returns the full content of the file as a single string.

If you want to loop over the lines, you need to split the result as in the following example:

---
- hosts: localhost
  gather_facts: false

  vars:
    file_content: |-
      first line
      second line
      third line

  tasks:
    - debug:
        msg: "{{ file_content.split('\n') }}"

which gives:

TASK [debug] ***************************************************
ok: [localhost] => {
    "msg": [
        "first line",
        "second line",
        "third line"
    ]
}

Upvotes: 2

Related Questions