提取没有扩展名的文件名 - Ansible

doc*_*oob 6 ansible

我有一个像下面这样的variable文件ansible

check:
       - file1.tar.gz
       - file2.tar.gz

Run Code Online (Sandbox Code Playgroud)

在迭代它时tasks我正在使用{{item}}

with_items: - "{{check}}",

有没有办法在迭代时提取没有扩展名的文件名?即我需要file1来自file1.tar.gzfile2来自file2.tar.gz

Sun*_*kya 6

试试这个我在我的代码中使用了这个,例如:

  vars:
    check:
      - file1.tar.gz
      - file2.tar.gz

  tasks:
    - name: Apply filter while looping
      debug:
        msg: >-
          {{ item | splitext | first | splitext | first }}
      loop: "{{ check }}"
Run Code Online (Sandbox Code Playgroud)


Zei*_*tor 5

Ansible 有作为splitext过滤器,但不幸的是它只在最后一个点之后拆分扩展名。

可靠地实现您的要求 IMO 的唯一解决方案是使用对象上可用的split()python 方法stringregex_replace过滤器

regexp 解决方案对于您当前的需求来说有点过头了。同时它非常灵活,因为您可以轻松地使其适应更复杂的情况(匹配名称中的语义版本,寻找特定模式)。此外,由于它是一个过滤器(相对于 的python 本地方法.split()),您可以使用它:

  • 循环时,对每个项目应用过滤器
  • 在使用过滤器循环将其应用于整个列表之前map

以下是以下剧本中每个解决方案的示例:

---
- name: Extract file name without extension(s)
  hosts: localhost
  gather_facts: false

  vars:
    check:
      - file1.tar
      - file2.tar.gz
      - file3.tar.bz2.back
      - a_weird_file.name.with.too.many.dots

    file_regex: >-
      ^([^\.]*).*

  tasks:
    - name: use the split() function
      debug:
        msg: >-
          {{ item.split('.') | first }}
      loop: "{{ check }}"

    - name: Apply regex filter while looping
      debug:
        msg: >-
          {{ item | regex_replace(file_regex, '\1') }}
      loop: "{{ check }}"

    - name: Apply regex filter on list before loop
      debug:
        var: item
      loop: >-
        {{ check | map('regex_replace', file_regex, '\1') | list }}
Run Code Online (Sandbox Code Playgroud)

这是结果。

注意:就我自己的知识而言,我在运行剧本时使用了profile_task回调插件。你会看到在这个小文件列表中,每种方法都有相同的性能

$ ansible-playbook playbook.yml 

PLAY [Extract file name without extension(s)] *************************************************

TASK [use the split() function] ************************************************************
Friday 02 April 2021  18:53:14 +0200 (0:00:00.019)       0:00:00.019 ********** 
ok: [localhost] => (item=file1.tar) => {
    "msg": "file1"
}
ok: [localhost] => (item=file2.tar.gz) => {
    "msg": "file2"
}
ok: [localhost] => (item=file3.tar.bz2.back) => {
    "msg": "file3"
}
ok: [localhost] => (item=a_weird_file.name.with.too.many.dots) => {
    "msg": "a_weird_file"
}

TASK [Apply regex filter while looping] ****************************************************
Friday 02 April 2021  18:53:14 +0200 (0:00:00.056)       0:00:00.075 ********** 
ok: [localhost] => (item=file1.tar) => {
    "msg": "file1"
}
ok: [localhost] => (item=file2.tar.gz) => {
    "msg": "file2"
}
ok: [localhost] => (item=file3.tar.bz2.back) => {
    "msg": "file3"
}
ok: [localhost] => (item=a_weird_file.name.with.too.many.dots) => {
    "msg": "a_weird_file"
}

TASK [Apply regex filter on list before loop] **********************************************
Friday 02 April 2021  18:53:14 +0200 (0:00:00.056)       0:00:00.132 ********** 
ok: [localhost] => (item=file1) => {
    "ansible_loop_var": "item",
    "item": "file1"
}
ok: [localhost] => (item=file2) => {
    "ansible_loop_var": "item",
    "item": "file2"
}
ok: [localhost] => (item=file3) => {
    "ansible_loop_var": "item",
    "item": "file3"
}
ok: [localhost] => (item=a_weird_file) => {
    "ansible_loop_var": "item",
    "item": "a_weird_file"
}

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

Friday 02 April 2021  18:53:14 +0200 (0:00:00.057)       0:00:00.189 ********** 
=============================================================================== 
Apply regex filter on list before loop --------------------------------- 0.06s
Apply regex filter while looping --------------------------------------- 0.06s
use the split() function ----------------------------------------------- 0.06s 
Run Code Online (Sandbox Code Playgroud)

  • 好例子。唯一需要注意的是,如果您的文件名包含多个句点(例如:file-v1.2.3.tar.gz)。用户可能必须列出常用文件扩展名,并在它们出现在完整文件名末尾时将其删除。 (2认同)