首页 > 解决方案 > Exclude the three first items of a sorted list

问题描述

How can I print a sorted list excluding its three first items?
Below is my Ansible playbook:

- set_fact:
    filesDel: "{{ filesDel|default({})|
                  combine({item.NameOfFile: findFiles.files|
                  sort(attribute='mtime', reverse = true)|
                  map(attribute='path')|
                  select('search', item.NameOfFile)|
                  list}) }}"
  with_items:
    - "{{ fileList }}"


I tried this, but it is not working

- debug:
    msg: "{{ item.value[0:-3] }}"
  with_dict:
    - "{{ filesDel }}"
  loop_control:
    label: "{{ item.key }}"

When I removed [0:-3], I do get the whole list of data grouped by file name, for instance:

 ok: [142.20.10.15] => (item=fileName.png) => {
    "msg": [
        "/filePathA/fileName.png.25751.2020-08-31@19:30:59~",
        "/filePathB/fileName.png.25752.2020-08-31@19:30:59~", 
        "/filePathB/fileName.png.25751.2020-08-30@22:30:59~",
        "/filePathB/fileName.png.2222.2020-08-31@19:30:59~",
        "/filePathB/fileName.png.2222.2020-08-31@19:30:59~", 
        "/filePathA/fileName.png.2222.2020-08-30@22:30:59~"
    ]
}       

When I add [0:-3], I get:

ok: [142.20.10.15] => (item=fileName.png) => {
    "msg": [
        "/filePathA/fileName.png.25751.2020-08-31@19:30:59~",
        "/filePathB/fileName.png.25752.2020-08-31@19:30:59~", 
        "/filePathB/fileName.png.25751.2020-08-30@22:30:59~"
    ]
}

This not correct as those files are the first 3 files.
What I want is to exclude those 3 files, so, I should get:

 ok: [142.20.10.15] => (item=fileName.png) => {
    "msg": [
        "/filePathB/fileName.png.2222.2020-08-31@19:30:59~",
        "/filePathB/fileName.png.2222.2020-08-31@19:30:59~", 
        "/filePathA/fileName.png.2222.2020-08-30@22:30:59~"
    ]
} 

What am I doing wrong here?


Basically, the files are sorted based on the time they were created.

标签: ansible

解决方案


The slicing syntax of Python that you can use in Ansible works like this:

[start:end:step]

For reference, see https://docs.python.org/3/library/functions.html#slice

In this syntax, if you use a negative value, the reference is not the beginning of the list but the end.
Still, in this syntax, any element can be left empty, where [:] would actually means from the beginning to the end of the list.

So your actual trial [0:-3] means that you want

  • the items from the first element of the list (start: 0)
  • until the end - 3 of the list (end: -3)

If you want all the element except the three first then, you need

  • the items from the third element of the list (start: 3)
  • until the end of the list (end: – so it stays empty)

So your correct slice notation is [3:].

Given the playbook:

- hosts: all
  gather_facts: no
      
  tasks:
    - debug: 
        msg: "{{ filesDel[3:] }}"
      vars:
        filesDel:
          - "/filePathA/fileName.png.25751.2020-08-31@19:30:59~"
          - "/filePathB/fileName.png.25752.2020-08-31@19:30:59~" 
          - "/filePathB/fileName.png.25751.2020-08-30@22:30:59~"
          - "/filePathB/fileName.png.2222.2020-08-31@19:30:59~"
          - "/filePathB/fileName.png.2222.2020-08-31@19:30:59~" 
          - "/filePathA/fileName.png.2222.2020-08-30@22:30:59~"

This yields:

PLAY [all] ***********************************************************************************************************

TASK [debug] *********************************************************************************************************
ok: [localhost] => {
    "msg": [
        "/filePathB/fileName.png.2222.2020-08-31@19:30:59~",
        "/filePathB/fileName.png.2222.2020-08-31@19:30:59~",
        "/filePathA/fileName.png.2222.2020-08-30@22:30:59~"
    ]
}

PLAY RECAP ***********************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

推荐阅读