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

Adr*_*ire 3 shell jq

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

$ 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
  }
]
Run Code Online (Sandbox Code Playgroud)

如您所见,最后一个命令没有解释管道数据。

现在,我被迫将第一个操作的输出保存到一个临时文件中,以便我可以在将其发送回网络之前执行 jq 合并操作。拥有一个流会更有效率

pea*_*eak 5

我想将文件中的一些数据添加到标准输出管道中的提要中。

有多种方法可以做到这一点,具体取决于 shell 以及您使用的 jq 版本。

假设您的 jq 支持 --argfile 选项,您可能会发现这非常合适:

cat /tmp/a1 | jq --argfile a2 /tmp/a2 '. + $a2'
Run Code Online (Sandbox Code Playgroud)

这是另一种变体,暗示了其他一些可能性:

jq -n --argfile a1 <(cat /tmp/a1) --argfile a2 <(cat /tmp/a2) '$a1 + $a2'
Run Code Online (Sandbox Code Playgroud)

更有趣的是:

(cat /tmp/a1 ; cat /tmp/a2) | jq '. + input' 
Run Code Online (Sandbox Code Playgroud)

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

jq -s '.[0] + .[1]' <(cat /tmp/a1) /tmp/a2
Run Code Online (Sandbox Code Playgroud)

不过,一般而言,最好避免该-s选项。

关于啜饮的注意事项

如果您比较以下产生的输出:

echo '1 2' |
  jq -s --debug-dump-disasm --debug-trace  '.[0], .[1]'
Run Code Online (Sandbox Code Playgroud)

echo '1 2' |
  jq --debug-dump-disasm --debug-trace  '., input'
Run Code Online (Sandbox Code Playgroud)

您会注意到前者必须使用 PUSHK_UNDER 来存储整个数组[1,2],而后者程序只是分别读取两个输入。

在第一个程序中,直到所有指向数组的指针都被处理后才能释放数组的内存,而在第二个程序中, . 可以在第一次 RET 后释放。