shell 具有来自不同源的多个输入的jq

cld4siwp  于 2022-11-16  发布在  Shell
关注(0)|答案(3)|浏览(188)

在使用jq时,我们如何混合不同的输入源?对于一个特定的用例,我想将一些数据从一个文件添加到一个在stdout中是管道的提要中。

$ echo '[{"a": 1}]' > /tmp/a1
$ echo '[{"a": 2}]' > /tmp/a2
$ jq --slurp '.[0] + .[1]' /tmp/a1 /tmp/a2
[
  {
    "a": 1
  },
  {
    "a": 2
  }
]
$ cat /tmp/a1 | jq --slurp '.[0] + .[1]' /tmp/a2  # Expecting the same result
[
  {
    "a": 2
  }
]

正如您所看到的,最后一个命令没有解释管道数据。
现在,我不得不将第一个操作的输出保存到一个临时文件中,以便在将其发送回网络之前可以执行jq合并操作。

jpfvwuh4

jpfvwuh41#

我想将文件中的一些数据添加到stdout中的feed中。
有多种方法可以做到这一点,这取决于shell和您使用的jq版本。
假设您的jq支持--argfile选项,您可能会发现这非常合适:

cat /tmp/a1 | jq --argfile a2 /tmp/a2 '. + $a2'

下面是另一个变体,它暗示了其他一些可能性:

jq -n --argfile a1 <(cat /tmp/a1) --argfile a2 <(cat /tmp/a2) '$a1 + $a2'

更有趣的是:

(cat /tmp/a1 ; cat /tmp/a2) | jq '. + input'

最后一个方法应该适用于所有版本的jq:

jq -s '.[0] + .[1]' <(cat /tmp/a1) /tmp/a2

不过,一般来说,最好避免使用-s选项。
关于吸溜的注意事项
如果比较以下各项产生的输出:

echo '1 2' |
  jq -s --debug-dump-disasm --debug-trace  '.[0], .[1]'

echo '1 2' |
  jq --debug-dump-disasm --debug-trace  '., input'

您会注意到,前者必须使用PUSHK_UNDER来存储整个数组[1,2],而后者只需要分别读取两个输入。
在第一个程式中,数组的内存必须等到所有指向它的指标都已行程之后才能释放,而在第二个程式中,.的内存可以在第一个RET之后释放。

drnojrws

drnojrws2#

可以这样做,其中cat转发其stdin,后跟a2

<GENERATE a1> | cat - /tmp/a2 | jq --slurp '.[0] + .[1]'

或者,这是一个 * 复合语句 *,将两个单独命令的结果传递到管道中:

{ <GENERATE a1> ; cat /tmp/a2; } | jq --slurp '.[0] + .[1]'

注意大括号旁边要有空格,最后一个括号前面要有分号。

y4ekin9u

y4ekin9u3#

完成peak的回答,实际上不需要重定向:
jq -n --argfile a1 /tmp/a1 --argfile a2 /tmp/a2 '$a1 + $a2'

相关问题