jq:将数组转换为文件名索引的对象?
jq: convert array to object indexed by filename?
如何使用 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”文件扩展名如果可能,只删除基本名称(不包括目录)。
例子
file1.json
{ "roles": ["mysql"] }
file2.json
{ "roles": ["mysql", "php"] }
file3.json
{ }
我的真实文件中显然也有其他内容,但这对于本示例来说应该足够了。 file3 只是为了证明 "roles" 有时会丢失。
换句话说:我试图在 "roles" 列表中找到包含 "mysql" 的文件。我需要将文件名和内容组合成一个 JSON 对象。
进一步简化问题:
jq 'input_filename' f1 f2
给我所有我想要的文件名,但我不知道如何将它们组合成一个对象或数组。
然而,
jq -s 'map(input_filename)' f1 f2
给我 相同的 文件名,每个文件重复一次。例如[ "f1", "f1" ]
而不是 [ "f1", "f2" ]
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"
]
}
}
如果您的 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
如何使用 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”文件扩展名如果可能,只删除基本名称(不包括目录)。
例子
file1.json{ "roles": ["mysql"] }
file2.json
{ "roles": ["mysql", "php"] }
file3.json
{ }
我的真实文件中显然也有其他内容,但这对于本示例来说应该足够了。 file3 只是为了证明 "roles" 有时会丢失。
换句话说:我试图在 "roles" 列表中找到包含 "mysql" 的文件。我需要将文件名和内容组合成一个 JSON 对象。
进一步简化问题:
jq 'input_filename' f1 f2
给我所有我想要的文件名,但我不知道如何将它们组合成一个对象或数组。
然而,
jq -s 'map(input_filename)' f1 f2
给我 相同的 文件名,每个文件重复一次。例如[ "f1", "f1" ]
而不是 [ "f1", "f2" ]
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"
]
}
}
如果您的 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