我刚刚看到了一个使用将多个事物放入管道的示例(用于)。echo
jq
echo '{"A": {"a": 1}}' '{"A": {"b": 2}}' '{"B": 3}' |\
jq --slurp 'reduce .[] as $item ({}; . * $item)'
如果我理解正确的话,这似乎在一端将三个对象放入管道,在另一端jq
接收它们并将它们放入数组中,并使用合并运算符将其减少。
这让我很惊讶,我不确定如何在 中拥有多个东西stdin
。
更具体地说,系统如何知道输入是三个文件以及每个文件在哪里开始/结束?
如果我只执行回显部分echo '{"A":1}' '{"A": {"b": 2}}' '{"B": 3}'
,则输出似乎在三个对象之间没有任何可见的分隔符:
{"A":1} {"A": {"b": 2}} {"B": 3}
单引号是否有一些特殊效果,可以告诉下一个过滤器(jq
)边界?或者 jq 如何知道边界?
(这是 Ubuntu 24.04,jq 1.7.1)
它什么都没做。没有对象;只有字符“流”。
echo
打印它获得的所有参数,以空格分隔。如果这样做echo 'a' 'b' 'c'
,则输出将是a b c
;单个流类似地,您的 echo 语句只会产生输出
{"A": {"a": 1}} {"A": {"b": 2}} {"B": 3}
。同样,只是一个字符流。该
jq
命令对 JSON 有足够多的了解,知道这些字符有一定的含义(一组单独的 JSON 对象),但对于echo
管道来说,它只是一串无意义的字符。如果你这样做,你会得到完全相同的结果
echo '{"A": {"a": 1}} {"A": {"b": 2}} {"B": 3}'
。或者甚至像echo '{"A":' '{"a":' "1}}" '{"A": {"b": 2}} {"B": 3}'
还要注意,你可以将多个命令的输出发送到管道,结果仍然只是所有相关字节的连接。例如,这里
foobar
连接成一行: