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"]
.
我想要一个 不使用 的解决方案,使用 slurp
或 inputs
。
谢谢。
I want a solution without using slurp or inputs.
不幸的是,除非您愿意调用 jq 两次,否则这是 jq 必须提供的仅有的两个选项,除非您允许 input
。 gojq 和 jaq 也是如此。
如果您的输入是 JSONL(每行一个 JSON),那么当然有许多明显的方法来预处理流以实现“slurping”效果。否则,您可能想要使用 JSON-oriented 工具来补充 jq,或者使用它。
我不认为这是一个非常实用的解决方案,但您可以通过使用对 jq
的第二次调用和适当的转换编码,将范围从逐项流切换到包络单例,因此使用 -j
和 -R
写入和读取单行原始文本。从技术上讲,这可以满足您的要求(不使用 slurp
或 inputs
),但这值得吗?
一种这样的方法是通过添加逗号和括号从已经 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-input
和input
:
#!/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).
我有:
过滤器:
["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"]
.
我想要一个 不使用 的解决方案,使用 slurp
或 inputs
。
谢谢。
I want a solution without using slurp or inputs.
不幸的是,除非您愿意调用 jq 两次,否则这是 jq 必须提供的仅有的两个选项,除非您允许 input
。 gojq 和 jaq 也是如此。
如果您的输入是 JSONL(每行一个 JSON),那么当然有许多明显的方法来预处理流以实现“slurping”效果。否则,您可能想要使用 JSON-oriented 工具来补充 jq,或者使用它。
我不认为这是一个非常实用的解决方案,但您可以通过使用对 jq
的第二次调用和适当的转换编码,将范围从逐项流切换到包络单例,因此使用 -j
和 -R
写入和读取单行原始文本。从技术上讲,这可以满足您的要求(不使用 slurp
或 inputs
),但这值得吗?
一种这样的方法是通过添加逗号和括号从已经 JSON-encoded 的部分手动构建 JSON 数组:
首先,使用 tojson
将项目编码为 JSON,并在每个项目后附加一个逗号。在第二个实例中,删除最后一个字符(多余的逗号),将字符串括在括号中,并使用 fromjson
.
jq -j '"key:\(.key)", "value:\(.value)" | "\(tojson),"' | jq -R '"[\(.[:-1])]" | fromjson'
[
"key:state",
"value:pending",
"key:options",
"value:request"
]
如果可以使用--null-input
和input
:
#!/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).