【问题标题】:jq: convert array to object indexed by filename?jq:将数组转换为按文件名索引的对象?
【发布时间】:2018-07-06 20:11:08
【问题描述】:

使用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)。


示例

文件1.json
{ "roles": ["mysql"] }
文件2.json
{ "roles": ["mysql", "php"] }
文件 3.json
{ }

我的真实文件中显然也有其他内容,但对于这个例子来说应该足够了。 file3 只是为了证明有时缺少“角色”。

换句话说:我正在尝试在其“角色”列表中查找包含“mysql”的文件。我需要将文件名和内容合并到一个 JSON 对象中。


为了进一步简化问题:

jq 'input_filename' f1 f2

给我想要的所有文件名,但我不知道如何将它们组合成一个对象或数组。

然而,

jq -s 'map(input_filename)' f1 f2

给我相同的文件名,每个文件重复一次。例如[ "f1", "f1" ] 而不是 [ "f1", "f2" ]

【问题讨论】:

  • 发布最小且可测试的输入 json 内容(来自您的输入文件)
  • @RomanPerekhrest 添加。我认为必须在单独的文件中,无法从 stdio 读取,因为这个问题与文件名有关。
  • 我可能已经找到了解决方案。我可以运行 JQ 两次:jq 'input_filename' $^ | jq -s

标签: json jq pathname


【解决方案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

【讨论】:

  • 如果我理解这一点,any(.roles[]; contains("mysql")) 实际上的意思是“如果任何角色包含 子字符串 'mysql'”不是吗?对于精确等价,any(.roles[]; . == "mysql") 不是更合适吗?
  • 我只使用了“包含”,因为那是原始问题中的内容,并且与之等效。但是,如果您需要字符串相等,那么您当然会使用==
  • 啊……很公平。那是我的错误:-)当我第一次找到它时,我认为它就像一个“数组包含”:D
【解决方案2】:

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"
    ]
  }
}

【讨论】:

  • 漂亮!不知道if。也可以用select:jq 'select (.roles[]? | contains("mysql")) | {(input_filename | gsub(".*/|\\.json$$";"")): .}' $^ | jq -s 'add'(格式化为Make)来完成
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-30
  • 2017-07-14
  • 1970-01-01
  • 2022-10-07
  • 2023-01-24
  • 1970-01-01
相关资源
最近更新 更多