如何使用jq将数组转换为按文件名索引的对象,或将多个文件读入按文件名索引的对象?
例如
jq -s 'map(select(.roles[]? | contains ("mysql")))' -C dir/file1.json dir/file2.json
这给了我我想要的数据,但是我需要知道它们来自哪个文件。
所以不是
[
{ "roles": ["mysql"] },
{ "roles": ["mysql", "php"] }
]
对于输出,我想要:
{
"file1": { "roles": ["mysql"] },
"file2": { "roles": ["mysql", "php"] }
}
如果可能,我确实希望将“ .json”文件扩展名也剥离掉, ,而只是去除基名(不包括dir)。
{ "roles": ["mysql"] }
file2.json
{ "roles": ["mysql", "php"] }
file3.json
{ }
我的真实文件中显然还包含其他内容,但这对于本示例来说已经足够了。 file3只是为了证明有时会丢失“角色”。
换句话说:我正在尝试在“角色”列表中查找包含“ mysql”的文件。我需要将文件名和内容组合到一个JSON对象中。
为进一步简化问题,
jq 'input_filename' f1 f2
为我提供所有想要的文件名,但是我不知道如何将它们组合成一个对象或数组。
而
jq -s 'map(input_filename)' f1 f2
给我相同的文件名,每个文件重复一次。例如[ "f1", "f1" ]
代替[ "f1", "f2" ]
答案 0 :(得分:1)
jq
方法:
jq 'if (.roles[] | contains("mysql")) then {(input_filename | gsub(".*/|\\.json$";"")): .}
else empty end' ./file1.json ./file2.json | jq -s 'add'
预期输出:
{
"file1": {
"roles": [
"mysql"
]
},
"file2": {
"roles": [
"mysql",
"php"
]
}
}
答案 1 :(得分:1)
如果jq具有inputs
(jq 1.5也是如此),则只需调用一次jq即可完成任务。
另外,使用any
可能比遍历.roles
的所有元素更有效。
技巧是使用-n选项调用jq,例如
jq -n '
[inputs
| select(.roles and any(.roles[]; contains("mysql")))
| {(input_filename | gsub(".*/|\\.json$";"")): .}]
| add' file*.json