英文:
How to create a new attribute using items from a list and append it back to the same list of dictionaries?
问题
我可以帮您翻译代码部分:
- set_fact:
FullName: "{{ item.FirstName + ' ' + item.LastName }}"
loop: "{{ data }}"
请注意,您可以使用上面的代码将 FullName
属性添加到每个字典中,但这将结果存储在 ansible_facts.FullName
中。如果您想要将结果存储在 item.FullName
中,您可以尝试以下方法:
- set_fact:
item.FullName: "{{ item.FirstName + ' ' + item.LastName }}"
loop: "{{ data }}"
这应该会将 FullName
属性添加到每个字典中的 item
变量中。希望这可以帮助您达到预期的输出。
英文:
I have this list:
{
"data": [
{
"ClassType": "Part Time",
"FirstName": "Monice",
"LastName": "Lee"
},
{
"ClassType": "Full Time",
"FirstName": "Henry Daley",
"LastName": "Brown"
}
]
}
How do I create a new attribute FullName
, which value would be FirstName + ' ' + LastName
and append this to all the dictionaries of the list?
Expected output:
{
"data": [
{
"ClassType": "Part Time",
"FirstName": "Monice",
"LastName": "Lee",
"FullName": "Monice Lee"
},
{
"ClassType": "Full Time",
"FirstName": "Henry Daley",
"LastName": "Brown",
"FullName": "Henry Daley Brown"
}
]
}
I tried this approach:
- set_fact:
FullName: "{{ item.FirstName + ' ' + item.LastName }}"
loop: "{{ data }}"
However, the new variable ended up appearing under ansible_facts.FullName
and not item.FullName
.
Output
ok: [localhost] => (item={'FirstName': 'Henry Daley', 'LastName': 'Brown', 'ClassType': 'Full Time'}) => {
"ansible_facts": {
"FullName": "Henry Daley Brown"
},
"ansible_loop_var": "item",
"changed": false,
"item": {
"ClassType": "Full Time",
"FirstName": "Henry Daley",
"LastName": "Brown"
}
}
ok: [localhost] => (item={'FirstName': 'Monice', 'LastName': 'Lee', 'ClassType': 'Part Time'}) => {
"ansible_facts": {
"FullName": "Monice Lee"
},
"ansible_loop_var": "item",
"changed": false,
"item": {
"ClassType": "Part Time",
"FirstName": "Monice",
"LastName": "Lee"
}
}
How can I create/append this FullName
attribute each dictionary of the list?
答案1
得分: 3
你可以使用 JMESPath 的 join
函数来更新你的字典。
给定的任务:
- set_fact:
data: >-
{{
data | json_query("
[].{
ClassType: ClassType,
FirstName: FirstName,
LastName: LastName,
FullName: join(' ', [FirstName, LastName])}
")
}}
vars:
data:
- ClassType: Full Time
FirstName: Henry Daley
LastName: Brown
- ClassType: Part Time
FirstName: Monice
LastName: Lee
你的 data
变量将根据你的需求更新为:
ok: [localhost] => changed=false
ansible_facts:
data:
- ClassType: Full Time
FirstName: Henry Daley
FullName: Henry Daley Brown
LastName: Brown
- ClassType: Part Time
FirstName: Monice
FullName: Monice Lee
LastName: Lee
注意:上述输出是在运行带有 -v
选项的 Playbook 时生成的,其中包括了 set_fact
任务的结果等有用信息。
英文:
You could use the join
function of JMESPath to update your dictionary.
Given the task:
- set_fact:
data: >-
{{
data | json_query("
[].{
ClassType: ClassType,
FirstName: FirstName,
LastName: LastName,
FullName: join(' ', [FirstName, LastName])}
")
}}
vars:
data:
- ClassType: Full Time
FirstName: Henry Daley
LastName: Brown
- ClassType: Part Time
FirstName: Monice
LastName: Lee
Your data
variable would be updated according to your need:
ok: [localhost] => changed=false
ansible_facts:
data:
- ClassType: Full Time
FirstName: Henry Daley
FullName: Henry Daley Brown
LastName: Brown
- ClassType: Part Time
FirstName: Monice
FullName: Monice Lee
LastName: Lee
<sup>Note: the above output have been generated running the playbook with the option -v
, which, amongst other useful information, shows the result of a set_fact
task.</sup>
答案2
得分: 2
Create list *update*
```yaml
update: "{{ data|json_query('[].[FirstName, LastName]')|
map('join', ' ')|
map('community.general.dict_kv','FullName') }}"
Optionally, the query below gives the same result
fn_query: "[].{FullName: join(' ', [FirstName, LastName])}"
update: "{{ data|json_query(fn_query) }}"
gives
update:
- FullName: Monice Lee
- FullName: Henry Daley Brown
Update data
- set_fact:
data: "{{ data|zip(update)|map('combine') }}"
gives
data:
- ClassType: Part Time
FirstName: Monice
FullName: Monice Lee
LastName: Lee
- ClassType: Full Time
FirstName: Henry Daley
FullName: Henry Daley Brown
LastName: Brown
Example of a complete playbook for testing
- hosts: localhost
vars:
data:
- ClassType: Part Time
FirstName: Monice
LastName: Lee
- ClassType: Full Time
FirstName: Henry Daley
LastName: Brown
update: "{{ data|json_query('[].[FirstName, LastName]')|
map('join', ' ')|
map('community.general.dict_kv','FullName') }}"
tasks:
- debug:
var: update
- set_fact:
data: "{{ data|zip(update)|map('combine') }}"
- debug:
var: data
```
英文:
Create list update
update: "{{ data|json_query('[].[FirstName, LastName]')|
map('join', ' ')|
map('community.general.dict_kv','FullName') }}"
<hr>
<sup>
Optionally, the query below gives the same result
fn_query: "[].{FullName: join(' ', [FirstName, LastName])}"
update: "{{ data|json_query(fn_query) }}"
</sup>
<hr>
gives
update:
- FullName: Monice Lee
- FullName: Henry Daley Brown
Update data
- set_fact:
data: "{{ data|zip(update)|map('combine') }}"
gives
data:
- ClassType: Part Time
FirstName: Monice
FullName: Monice Lee
LastName: Lee
- ClassType: Full Time
FirstName: Henry Daley
FullName: Henry Daley Brown
LastName: Brown
<hr>
<sup>
Example of a complete playbook for testing
- hosts: localhost
vars:
data:
- ClassType: Part Time
FirstName: Monice
LastName: Lee
- ClassType: Full Time
FirstName: Henry Daley
LastName: Brown
update: "{{ data|json_query('[].[FirstName, LastName]')|
map('join', ' ')|
map('community.general.dict_kv','FullName') }}"
tasks:
- debug:
var: update
- set_fact:
data: "{{ data|zip(update)|map('combine') }}"
- debug:
var: data
</sup>
答案3
得分: 1
根据您的初始帖子
> ... 它最终出现在 ansible_facts.FullName
而不是 item.FullName
下...
这是正确的,也是预期的行为。
> 我如何将这个 FullName
变量创建/附加到 item
变量列表中
简短回答,你不能。至少不以那种方式,或者不更改 loop
的 Python 代码的情况下。这是因为循环变量不受任务的控制。可以考虑循环代码围绕任务代码。任务代码不知道外部有一个循环存在。
如果对更多细节或调试感兴趣,您可以查看在Ansible的交互式调试器中打印 item
。
解决您的问题的方法将是进行更复杂的数据操作,而不使用循环,并在其他答案中显示。
英文:
According your initial post
> ... it ended up appearing under ansible_facts.FullName
and not item.FullName
...
That's correct and the expected behavior.
> How can I create/append this FullName
variable to the list of item
variables
Short answer, you can't. At least not in that way and or without changing the Python code of loop
. This is because the loop variables are not under the control of the task. One could think about of that that the loop code is surrounding the task code. The task code is not aware of that there is a loop outside.
If interested in more details or debugging you may have a look into Print item
from interactive debugger in Ansible.
The solution for your problem will be a more complex data manipulation without a loop and is shown in the other answers here.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论