我正在尝试从字典中获取“计数”值
“ {\” _ id \“:ObjectId(\” 5d3a1643c43c898d01a3c740 \“),\” count \“:2}”
出现在ansible stdout_lines的最后一个元素上。
TASK [version_update : debug] ******************************************************************************************************************************************
ok: [192.168.27.125] => {
"count_info.stdout": "MongoDB shell version v4.0.6\nconnecting to: mongodb://127.0.0.1:27017/configure-db?gssapiServiceName=mongodb\nImplicit session: session { \"id\" : UUID(\"4bfad3ba-981f-47de-86f9-a1fadbe28e12\") }\nMongoDB server version: 4.0.6\n{ \"_id\" : ObjectId(\"5d3a1643c43c898d01a3c740\"), \"count\" : 2 }"
}
TASK [version_update : debug] ******************************************************************************************************************************************
ok: [192.168.27.125] => {
"count_info.stdout_lines": [
"MongoDB shell version v4.0.6",
"connecting to: mongodb://127.0.0.1:27017/configure-db?gssapiServiceName=mongodb",
"Implicit session: session { \"id\" : UUID(\"4bfad3ba-981f-47de-86f9-a1fadbe28e12\") }",
"MongoDB server version: 4.0.6",
"{ \"_id\" : ObjectId(\"5d3a1643c43c898d01a3c740\"), \"count\" : 2 }"
]
}
我尝试了以下两种方法,但没有成功。
- debug:
msg: "{{ (count_info.stdout_lines[-1] | from_json).count }}"
- name: count value
debug:
msg: "{{ count_info.stdout_lines[-1] | json_query('count') }}"
错误日志:
TASK [version_update : debug] ******************************************************************************************************************************************
fatal: [192.168.27.125]: FAILED! => {"msg": "the field 'args' has an invalid value ({u'msg': u'{{ (count_info.stdout_lines[-1] | from_json).count }}'}), and could not be converted to an dict.The error was: No JSON object could be decoded\n\nThe error appears to have been in '/home/admin/playbook-3/roles/version_update/tasks/version_update.yml': line 73, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- debug:\n ^ here\n"}
to retry, use: --limit @/home/admin/playbook-3/version_update.retry
TASK [version_update : count value] ************************************************************************************************************************************
ok: [192.168.27.125] => {
"msg": ""
}
答案 0 :(得分:0)
输出中的最后一行不是纯json字符串(可能是bson from a your MongoDB output)。您收到的错误实际上是由于过滤器本身未获得正确的输入而导致的。
在使用from_json
过滤器之前,您必须将其转换为纯json。有问题的数据是ObjectId(\"5d3a1643c43c898d01a3c740\")
,无法由过滤器反序列化。这应该在用于注册变量的任务/命令中更改。您可以在this interesting question上找到有关该主题的许多答案,这些答案可能会为您提供一些线索。
一旦完成,访问数据就变得很容易了,就像您已经知道的那样。这是一个示例,其示例数据经过修改(我认为您应该最终得到它),只是为了确认您在正确的位置上。
- name: Get count in json serialized string
hosts: localhost
gather_facts: false
vars:
"count_info":
"stdout_lines": [
"MongoDB shell version v4.0.6",
"connecting to: mongodb://127.0.0.1:27017/configure-db?gssapiServiceName=mongodb",
"Implicit session: session { \"id\" : UUID(\"4bfad3ba-981f-47de-86f9-a1fadbe28e12\") }",
"MongoDB server version: 4.0.6",
"{ \"_id\" : \"someDeserializedId\", \"count\" : 2 }"
]
tasks:
- name: Get count
debug:
msg: "{{ (count_info.stdout_lines[-1] | from_json).count }}"
结果
PLAY [Get count in json serialized string] ********************************************************************************************************************************************************************************
TASK [Get count] **********************************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "2"
}
答案 1 :(得分:0)
尽管该元素具有字典的结构,但实际上它是一个字符串,我无法使用to_json
或to_nice_json
对其进行过滤以将其转换为字典。
使用以下任务序列将获得您想要获取的值,不幸的是,我没有找到一种在一项任务中做到这一点的方法。逻辑如下:
从列表中获取最后一个元素,并将字符串拆分为键值子字符串,并用,
分隔。
分析此列表并找到包含关键字count
的元素(如果您认为count
也可能出现在其他行中,则可以在此处进行增强)。然后使用正则表达式从中获取数值。
PB:
---
- hosts: localhost
gather_facts: false
vars:
final_count_value: -1
count_info:
stdout_lines:
- MongoDB shell version v4.0.6
- 'connecting to: mongodb://127.0.0.1:27017/configure-db?gssapiServiceName=mongodb'
- 'Implicit session: session { "id" : UUID("4bfad3ba-981f-47de-86f9-a1fadbe28e12")
}'
- 'MongoDB server version: 4.0.6'
- '{ "_id" : ObjectId("5d3a1643c43c898d01a3c740"), "count" : 2 }'
tasks:
- name: prepare list var
set_fact:
temp_list: "{{ (count_info.stdout_lines | last).split(', ') | list }}"
- name: find count
set_fact:
final_count_value: "{{ item | regex_replace('\"count\" : ', '') | regex_replace(' }', '') }}"
when: item is search('count')
with_items:
- "{{ temp_list }}"
- name: print result
debug:
var: final_count_value
输出:
PLAY [localhost] *******************************************************************************************************************************************************************************************************
TASK [prepare list var] ************************************************************************************************************************************************************************************************
ok: [localhost]
TASK [find count] ******************************************************************************************************************************************************************************************************
skipping: [localhost] => (item={ "_id" : ObjectId("5d3a1643c43c898d01a3c740"))
ok: [localhost] => (item="count" : 2 })
TASK [print result] ****************************************************************************************************************************************************************************************************
ok: [localhost] => {
"final_count_value": "2"
}
更新
要从结果中减去1,应使用:
- name: find count and subtract 1
set_fact:
final_count_value: "{{ item | regex_replace('\"count\" : ', '') | regex_replace(' }', '') | int - 1 }}"
when: item is search('count')
with_items:
- "{{ temp_list }}"
希望有帮助!