此方法是否用于使用 with_items 循环正确连接变量的字符串?
is this method used for string concatenation of variables using a with_items loop correct?
输入文件
[centos@linux1 tmp]$ cat data.txt
a car has 4 wheels
a bike has 2 wheels
输出文件
[centos@linux1 tmp]$ cat final_list
vehicle: car blah blah
vehicle: bike blah blah
剧本
[centos@linux1 tmp]$ cat test.yml
---
- hosts: localhost
tasks:
- name: check vehicle types
shell: "cat /tmp/data.txt | grep 'car\|bike' | awk '{print }'"
register: vehicle_list
- name : create a empty string variable
set_fact:
var1: ''
- name: concate strings
set_fact:
var1: "{{var1}}\nvehicle: {{item}} blah blah"
with_items: "{{vehicle_list.stdout_lines}}"
- name: output to file
shell: echo "{{var1}}" >> /tmp/final_list
我能够得到想要的结果,但我认为代码不可读且其他人难以调试
问题:在 with_items 循环中用于连接任务 - name: concate strings
中的变量的方法是否正确
要么
有更清洁的方法吗?
我希望使用 or 中提到的连接方法
但我无法让他们工作
编辑:如何使用其他答案中描述的常规方法在带有项目的循环中实现字符串连接?
1) python 字符串连接
var1=var1+"vehicle: {{item}} blah blah\n"
2)加入过滤器
var1: "{{vehicle: {{item}} blah blah | join('\n') }}"
3)连接方法
var1: "{{ '\n'.join((vehicle: {{item}} blah blah)) }}"
我认为您可以在此处进行多项改进。首先,此命令不需要 cat
或 grep
:
- name: check vehicle types
shell: "cat /tmp/data.txt | grep 'car\|bike' | awk '{print }'"
register: vehicle_list
你可以只写:
- name: check vehicle types
command: "awk '/car|bike/ {print }' /tmp/data.txt"
register: vehicle_list
接下来,您不需要第一个 set_fact
语句,因为您可以利用 default
过滤器为尚未定义的 var1
提供值:
- name: concatenate strings
set_fact:
var1: "{{var1|default('')}}vehicle: {{item}} blah blah\n"
with_items: "{{vehicle_list.stdout_lines}}"
请注意,我还重新定位了 \n
,这样生成的文件就不会以空行开头。
最后,您正在使用 shell
任务将数据附加到文件中。如果你 实际上 不需要附加,你可以只使用 Ansible 的 copy
模块来创建你的输出文件:
- name: output to file
copy:
content: "{{ var1 }}"
dest: /tmp/final_list
如果你确实需要附加数据,而不是覆盖文件,那么你当前的解决方案是可以的,尽管我可能会这样写:
- name: output to file
shell: "cat >> /tmp/final_list"
args:
stdin: "{{ var1 }}"
上面的是一个"usual method",但你肯定有其他选择。如果你要建立一个行列表,像这样:
- name: create list
set_fact:
var1: "{{var1|default([]) + ['vehicle: %s blah blah' % (item)] }}"
with_items: "{{vehicle_list.stdout_lines}}"
然后您可以使用 join
过滤器来生成您的输出:
- name: output to file
copy:
content: "{{ var1|join('\n') }}"
dest: /tmp/final_list
或者使用字符串 .join
方法做同样的事情:
- name: output to file
copy:
content: "{{ '\n'.join(var1) }}"
dest: /tmp/final_list
输入文件
[centos@linux1 tmp]$ cat data.txt
a car has 4 wheels
a bike has 2 wheels
输出文件
[centos@linux1 tmp]$ cat final_list
vehicle: car blah blah
vehicle: bike blah blah
剧本
[centos@linux1 tmp]$ cat test.yml
---
- hosts: localhost
tasks:
- name: check vehicle types
shell: "cat /tmp/data.txt | grep 'car\|bike' | awk '{print }'"
register: vehicle_list
- name : create a empty string variable
set_fact:
var1: ''
- name: concate strings
set_fact:
var1: "{{var1}}\nvehicle: {{item}} blah blah"
with_items: "{{vehicle_list.stdout_lines}}"
- name: output to file
shell: echo "{{var1}}" >> /tmp/final_list
我能够得到想要的结果,但我认为代码不可读且其他人难以调试
问题:在 with_items 循环中用于连接任务 - name: concate strings
中的变量的方法是否正确
要么
有更清洁的方法吗?
我希望使用
编辑:如何使用其他答案中描述的常规方法在带有项目的循环中实现字符串连接?
1) python 字符串连接
var1=var1+"vehicle: {{item}} blah blah\n"
2)加入过滤器
var1: "{{vehicle: {{item}} blah blah | join('\n') }}"
3)连接方法
var1: "{{ '\n'.join((vehicle: {{item}} blah blah)) }}"
我认为您可以在此处进行多项改进。首先,此命令不需要 cat
或 grep
:
- name: check vehicle types
shell: "cat /tmp/data.txt | grep 'car\|bike' | awk '{print }'"
register: vehicle_list
你可以只写:
- name: check vehicle types
command: "awk '/car|bike/ {print }' /tmp/data.txt"
register: vehicle_list
接下来,您不需要第一个 set_fact
语句,因为您可以利用 default
过滤器为尚未定义的 var1
提供值:
- name: concatenate strings
set_fact:
var1: "{{var1|default('')}}vehicle: {{item}} blah blah\n"
with_items: "{{vehicle_list.stdout_lines}}"
请注意,我还重新定位了 \n
,这样生成的文件就不会以空行开头。
最后,您正在使用 shell
任务将数据附加到文件中。如果你 实际上 不需要附加,你可以只使用 Ansible 的 copy
模块来创建你的输出文件:
- name: output to file
copy:
content: "{{ var1 }}"
dest: /tmp/final_list
如果你确实需要附加数据,而不是覆盖文件,那么你当前的解决方案是可以的,尽管我可能会这样写:
- name: output to file
shell: "cat >> /tmp/final_list"
args:
stdin: "{{ var1 }}"
上面的是一个"usual method",但你肯定有其他选择。如果你要建立一个行列表,像这样:
- name: create list
set_fact:
var1: "{{var1|default([]) + ['vehicle: %s blah blah' % (item)] }}"
with_items: "{{vehicle_list.stdout_lines}}"
然后您可以使用 join
过滤器来生成您的输出:
- name: output to file
copy:
content: "{{ var1|join('\n') }}"
dest: /tmp/final_list
或者使用字符串 .join
方法做同样的事情:
- name: output to file
copy:
content: "{{ '\n'.join(var1) }}"
dest: /tmp/final_list