![保存管道值出错](https://linux22.com/image/68233/%E4%BF%9D%E5%AD%98%E7%AE%A1%E9%81%93%E5%80%BC%E5%87%BA%E9%94%99.png)
我安装了 jq 来使用 bash 处理一些 JSON。但不知何故,将 JSON 字符串传递给 jq 并将其输出保存到另一个变量时出现了错误。
TEST='{"foo": "bar"}'
PB_SIG=$TEST | jq '.foo'
echo $PB_SIG
它仅输出整个 TEST JSON 字符串。有人吗?
答案1
与 bash 一起使用:
TEST='{"foo": "bar"}'
PB_SIG=$(jq '.foo' <<< "$TEST")
echo "$PB_SIG"
输出:
“酒吧”
答案2
您的代码中存在一些问题。导致您当前问题的直接问题是您使用了错误的语法。要将命令或命令管道的输出保存在变量中,您可能需要使用命令替换variable=$(some command)
.
第二个问题是您对$TEST
未加引号的使用。当变量扩展未加引号时,shell 将在空格、制表符和换行符(变量的内容IFS
)上拆分其值,然后将文件名通配应用于每个拆分位。这意味着类似的 JSON 文档{"foo": "a * bar"}
最终可能会与当前目录中的所有可见文件名一起输出。
另一个问题是您使用 来echo
输出变量数据。如果 JSON 文档包含带有编码制表符 ( \t
) 或换行符 ( )的字符串\n
,则echo
可能会导致这些字符串扩展为文字制表符和换行符。以下问题及其答案更深入地讨论了这一点:为什么 printf 比 echo 更好?
由于您希望将 JSON 文档从 shell 变量传递到jq
表达式以提取顶级foo
键的值,因此我们可以这样做:
document='{"foo": "bar"}'
signature=$( jq -n -r --argjson data "$document" '$data.foo' )
这将创建一个jq
名为 的变量,data
其中包含 shell 变量中找到的 JSON 结构document
。然后,该jq
命令foo
从中提取密钥的值,而不从任何文件或数据流中读取任何数据(因为-n
已使用)。提取的字符串被解码(因为-r
已使用)并存储在 shell 变量 中signature
。
输出signature
变量的值:
printf '%s\n' "$signature"
...但是如果您只想输出该值,那么首先将其存储在 shell 变量中是没有意义的。相反,您可以jq
通过省略命令替换来直接输出值:
document='{"foo": "bar"}'
jq -n -r --argjson data "$document" '$data.foo'
答案3
在第二行尝试这个:
PB_SIG=`echo $TEST | jq '.foo'`
我看到的两个问题是,您需要通过管道回显 $TEST 变量的值,并且需要捕获管道命令的输出。