好的,我正在尝试编写一个脚本,该脚本从yum - repolist all
中获取信息,并将其放入漂亮的JSON中,以便我用于某些数据收集。.现在,我的yum命令输出如下这个。
我现在拥有的所有代码只是yum repolist命令。
#!/bin/bash -x
yum -v repolist all | grep -B2 -A6 "enabled" | sed 's/[[:space:]]//g' , 's/--//g' , 's/name=name=/name=/g'
该命令的输出如下:
Repo-id: wazuh_repo
Repo-name: Wazuhrepository
Repo-status: enabled
Repo-revision: 1536348945
Repo-updated: FriSep712:35:512018
Repo-pkgs: 73
Repo-size: 920M
Repo-baseurl: https://packages.wazuh.com/3.x/yum/
Repo-expire: 21,600second(s)(last:WedOct3108:59:002018)
大约有8个条目,标题始终是相同的...有人可以像我五岁时那样解释如何将其转换为json,我已经阅读了jq手册页,也已经了解了散列。似乎没有任何意义。我知道我需要一个“键” /“值”,如何指定这些?
我只想获取输出并使它看起来像漂亮的JSON,这是我正在编写的一个较大脚本的一部分,以帮助保持我们在工作中使用的存储库的顶部。我只是完全没有得到JSON。
编辑:我宁愿不使用包装器功能并做/学习正确的方法
答案 0 :(得分:2)
因此,首先,让没有yum
的人可以测试一下,让我们做一个包装函数:
write_output() { cat <<EOF
Repo-id: wazuh_repo
Repo-name: Wazuhrepository
Repo-status: enabled
Repo-revision: 1536348945
Repo-updated: FriSep712:35:512018
Repo-pkgs: 73
Repo-size: 920M
Repo-baseurl: https://packages.wazuh.com/3.x/yum/
Repo-expire: 21,600second(s)(last:WedOct3108:59:002018)
EOF
}
值得注意的是,您所有的键都在字符串:
之前,而值在它们之后-因此,我们想逐行读取,基于冒号-空格序列进行拆分,处理前面的内容作为键,然后将背后的内容视为值。
鉴于:
jq -Rn '[inputs | split(": ")] | reduce .[] as $kv ({}; .[$kv[0]] = $kv[1])' < <(write_output)
...正确发射:
{
"Repo-id": "wazuh_repo",
"Repo-name": "Wazuhrepository",
"Repo-status": "enabled",
"Repo-revision": "1536348945",
"Repo-updated": "FriSep712:35:512018",
"Repo-pkgs": "73",
"Repo-size": "920M",
"Repo-baseurl": "https://packages.wazuh.com/3.x/yum/",
"Repo-expire": "21,600second(s)(last:WedOct3108:59:002018)"
}
...那么,它如何工作?
jq -R
打开原始输入模式;输入被解析为原始字符串序列,而不是JSON文档序列。jq -n
将null
视为唯一的直接输入,因此可以在需要时在脚本中使用input
和inputs
原语。[ inputs ]
读取所有输入行,并将它们放入单个数组中。[ inputs | split(": ")]
将其从字符串数组更改为列表数组-内容在": "
序列之前和之后。reduce .[] as $kv ( {}; ... )
启动一个 reduceer ,其初始值为{}
,然后馈送.[]
求值的每个值(也就是说,每个列表中的项目)作为...
变量放入该化简器($kv
代码)中,每次替换.
值。要使用yum命令作为实际输入运行此命令,请将< <(write_output)
更改为< <(yum -v repolist all | grep -B2 -A6 "enabled" | sed 's/[[:space:]]//g' , 's/--//g' , 's/name=name=/name=/g')
。
答案 1 :(得分:0)
这里是@CharlesDuffy答案的更强大的变体。由于后者提供了很好的解释性注释,因此此处不再赘述。
jq -nR '
[inputs | index(": ") as $ix | {(.[:$ix]): .[$ix+2:]}]
| add'
在“值”包含“:”的情况下,这避免使用split
。但是,最好不要假设空格位于第一个相关的“:”之后。
还请注意,此处使用add
代替reduce
只是为了紧凑和简单。
答案 2 :(得分:0)
对于这类问题,我宁愿使用正则表达式来匹配键和值。否则,我将采用与Charles相似的方法。
$ ... | jq -Rn 'reduce (inputs | capture("(?<k>[^:]+):\\s*(?<v>.+)")) as {$k, $v} ({}; .[$k] = $v)'