JOIN 错误 & 在自定义描述前加上 JQ

JOIN error & Prepend custom description with JQ

提问人:Chenulu Peri 提问时间:11/12/2023 最后编辑:Jeff MercadoChenulu Peri 更新时间:11/12/2023 访问量:50

问:

我运行的命令生成 JSON 输出其他字段

{
  "description": "Test A",
  "planned_start": "2023-11-13T06:00:00Z",
  "planned_end": "2023-11-20T08:00:00Z",
  "priority": "low",
  ....
}
{
  "description": "Test B",
  "planned_start": "2023-11-13T06:00:00Z",
  "planned_end": "2023-11-20T06:00:00Z",
  "priority": "medium",
  ....
}
{
  "description": "Test C",
  "planned_start": "2023-11-13T06:00:00Z",
  "planned_end": "2023-11-20T06:00:00Z",
  "priority": "high",
  ....
}

我已经运行以下命令来选择我想要的字段。尝试查找如何获取以下输出。

command | jq -r '.[] | select (
  (.priority == "low") or (.priority == "high") or (.priority == "moderate")
)
| [.description, .planned_start, .planned_end]'

这会产生

[
 "Test A",
  "2023-11-13T06:00:00Z",
  "2023-11-20T06:00:00Z",
]
[
  "Test B",
  "2023-11-13T06:00:00Z",
  "2023-11-20T06:00:00Z",
]
[
  "Test C",
  "2023-11-13T06:00:00Z",
  "2023-11-20T06:00:00Z",
]

如果我添加联接,

command | jq -r '.[] | select (
  (.priority == "low") or (.priority == "high") or (.priority == "moderate")
)
| [.description, .planned_start, .planned_end | join(",")]'

我收到错误

无法循环访问字符串 (“Test A”)

Q1:如何修复错误
Q2:如何在每个值前面附加我自己的标头以获得以下输出

"Description": "Test A", "Start": "2023-11-13T06:00:00Z", "End": "2023-11-20T08:00:00Z"
"Description": "Test B", "Start": "2023-11-13T06:00:00Z", "End": "2023-11-20T06:00:00Z"
"Description": "Test C", "Start": "2023-11-13T06:00:00Z", "End": "2023-11-20T06:00:00Z"
JQ型

评论

0赞 pmf 11/12/2023
Q1:你在错误的地方使用。将其移到数组构造函数之外:.关于问题 2:请详细说明您的输出格式,因为它不再是 JSON(缺少大括号)。您想生成一个长字符串,如图所示,包括类似 JSON 的字段名称,还是希望将每个适当的 JSON 对象压缩为一行?对于这两种情况,构造最后一个数组并没有真正的帮助。| join(",")…] | join(",")
0赞 Chenulu Peri 11/12/2023
谢谢你的建议。将连接移到数组之外会产生我想要的输出。对于第二个问题,我想将自己的标签添加到输出中,并将适当的JSON对象压缩到每一行中

答:

1赞 pmf 11/12/2023 #1

关于Q1:

你在错误的地方使用。它需要一个数组,但通过在数组构造函数中,您可以为其提供数组的值,即字符串(因此出现错误消息)。将它移到数组构造函数之外,它将起作用:| join(",")Cannot iterate over string ("Test A")

… | [.description, .planned_start, .planned_end] | join(",")

关于Q2:

我想在输出中添加我自己的标签,并将适当的JSON对象压缩到每一行中

与其构造值数组,不如构造一个对象并根据需要命名字段。然后,使用该标志在 izs 自己的行上输出每个对象:-c

… | jq -c '.[] | select(IN(.priority; "low", "high", "moderate"))
| {Description: .description, Start: .planned_start, End: .planned_end}'

注意:我还使用值流将您的条件从多个 s 简化为单个。如果您使用的是 jq < 1.6,请改用。selectorINselect(any(.priority = ("low", "high", "moderate"); .))

评论

0赞 Chenulu Peri 11/12/2023
你的选择建议产生了我所要求的。还有一个问题:是否可以获取一个 JSON 数组,因此输出为 [ {“Description”: “Test A”, “Start”: “xxxx”, “End”: “xxx”}, { ... }, { ....}]
0赞 pmf 11/12/2023
@ChenuluPeri 当然,首先不要解构数组(你用 .相反,请使用 ,即 来执行所有操作。但是,使用数组作为结果,您不再有对象流,只有那一项(数组),因此标志会将所有对象放在一行中。如果这是你想要的,请使用它,或者删除标志以获得常规的漂亮打印的JSON。.[] | …map(…)map(select(…) | {Description: .description, …})-c
0赞 Jeff Mercado 11/12/2023 #2

要获得所需的输出,只需遍历对象列表并输出所需的属性即可。

由于输入似乎是流式传输的,因此您不想在开始时使用扩展,而是在此时迭代对象的值。只有当你的输入是一个数组时,你才需要它。这可能是您在 Q1 中看到的错误的原因。.[]

首先,选择要输出的属性。由于您想给它们一个不同的“标头”,因此您可以将其映射到一个对象。然后,您可以使用将对象转换为键/值对,并将每个对象对映射到您想要的呈现方式。由于您希望键和值用引号的字符串,因此可以使用它们加引号。使用要输出的字符串数组,可以联接该数组。to_entries/0tojson

$ command | jq -r '
select(.priority == ("low", "high", "moderate"))
  | { Description: .description, Start: .planned_start, End: .planned_end }
  | to_entries
  | map("\(.key|tojson): \(.value|tojson)")
  | join(", ")
'

JQPplay的