Jq 将多个字符串输入转换为一个更大的数组,无需 slurp 或输入

Jq Convert multiple string inputs to one larger array without slurp or inputs

我有:

过滤器:

["key:\(.key)", "value:\(.value)"][]

输入:

{"key":"state","value":"pending"}
{"key":"options","value":"request"}

输出:

"key:state"
"value:pending"
"key:options"
"value:request"

演示

https://jqplay.org/s/9yq89orzL0

我想将输出 "key:state" "value:pending" "key:options" "value:request" 转换为数组 ["key:state", "value:pending", "key:options", "value:request"]

我尝试了 reduce . as $s ([]; .+[$s]) 但这给出了 ["key:state"] ["value:pending"] ["key:options"] ["value:request"].

我想要一个 不使用 的解决方案,使用 slurpinputs

谢谢。

I want a solution without using slurp or inputs.

不幸的是,除非您愿意调用 jq 两次,否则这是 jq 必须提供的仅有的两个选项,除非您允许 input。 gojq 和 jaq 也是如此。

如果您的输入是 JSONL(每行一个 JSON),那么当然有许多明显的方法来预处理流以实现“slurping”效果。否则,您可能想要使用 JSON-oriented 工具来补充 jq,或者使用它。

我不认为这是一个非常实用的解决方案,但您可以通过使用对 jq 的第二次调用和适当的转换编码,将范围从逐项流切换到包络单例,因此使用 -j-R 写入和读取单行原始文本。从技术上讲,这可以满足您的要求(不使用 slurpinputs),但这值得吗?

一种这样的方法是通过添加逗号和括号从已经 JSON-encoded 的部分手动构建 JSON 数组:

首先,使用 tojson 将项目编码为 JSON,并在每个项目后附加一个逗号。在第二个实例中,删除最后一个字符(多余的逗号),将字符串括在括号中,并使用 fromjson.

解码准备好的 JSON 数组
jq -j '"key:\(.key)", "value:\(.value)" | "\(tojson),"' | jq -R '"[\(.[:-1])]" | fromjson'
[
  "key:state",
  "value:pending",
  "key:options",
  "value:request"
]

如果可以使用--null-inputinput

#!/usr/bin/env bash 
  
jq --null-input '
def loop:
    .+(input|["key:\(.key)", "value:\(.value)"]) |
    . as $res |
    try loop catch $res ;
loop
' << EOF
{"key":"state","value":"pending"}
{"key":"options","value":"request"}
EOF

输出:

[
  "key:state",
  "value:pending",
  "key:options",
  "value:request"
]

只是对 Philippe 回答的详细说明。

演示

https://jqplay.org/s/C_C-xudpVQ

过滤器

def to_array: .+[input] | . as $acc | try to_array catch $acc; to_array

输入

"foo is bar"
"goo is google"
"stack is over"
"over is flow"

输出

[
  "foo is bar",
  "goo is google",
  "stack is over",
  "over is flow"
]

to_array 函数中,在 each 迭代中,我们将 input 添加到单个数组并保存到 $acc (又名 'accumulated') ,直到 没有更多的 input,在这种情况下我们输出 $acc 直到那个点(因为 try 将失败在这种情况下,这将执行 catch exp).