如何将每个jq过滤器输出传递给外部命令?

时间:2019-03-31 21:36:05

标签: json pipe jq

我有一个包含JSON对象序列的大文件。每个对象都有一个我要提取并通过外部程序运行的值。您如何指示jq执行此操作?

例如,如果我有以下JSON文件:

{
  "id": 1,
  "corp": "Slate Rocks",
  "pubKey": "-----BEGIN PUBLIC KEY-----\nMFowDQYJKoZIhvcNAQEBBQADSQAwRgJBAMBUAZGIzQsPO1PXgjdCJUxcZNc6Y4FY\ncVC+JxZIUfaz0WkLI7H4tiKCsd+2F+3Xf+hObSbdoUi1UuT5uzpsda8CAQM=\n-----END PUBLIC KEY-----",
  "update": "2018-12-10"
}
{
  "id": 2,
  "corp": "Pi-ryte",
  "pubKey": "-----BEGIN PUBLIC KEY-----\nMFowDQYJKoZIhvcNAQEBBQADSQAwRgJBALzXcOJvZz2UFPDJphTm++Ho9t+lkTQf\nxH0nSp7lbfCHL5Y5YbnD7pgbD/e/PGIHt+cch3foOlUyH+b0Ht53ZO0CAQM=\n-----END PUBLIC KEY-----",
  "update": "2019-03-14"
}
{
  "id": 3,
  "corp": "Marble Dreams",
  "pubKey": "-----BEGIN PUBLIC KEY-----\nMFowDQYJKoZIhvcNAQEBBQADSQAwRgJBAN1L9v8ZbpJ1/GMlNOfGFjQhhO2KTKpj\nOfp97CDUdCAQ6wzLjagGKbySC16/MpnAvoPUmYEtTRtbdH/rdMGdvd8CAQM=\n-----END PUBLIC KEY-----",
  "update": "2018-12-17"
}

并且我想输出RSA公钥模数,我需要为每个openssl值执行"pubKey"

这仅适用于第一个"pubKey"

$ jq -r '.pubKey' seq.json | openssl rsa -pubin -noout -modulus
Modulus=C054019188CD0B0F3B53D7823742254C5C64D73A6381587150BE27164851F6B3D1690B23B1F8B62282B1DFB617EDD77FE84E6D26DDA148B552E4F9BB3A6C75AF

有没有类似的东西

$ jq -r '.pubKey | system("openssl rsa -pubin -noout -modulus")' seq.json

$ jq -r '.pubKey as $pk | system("openssl rsa -pubin -noout -modulus -in $pk")' seq.json

2 个答案:

答案 0 :(得分:2)

一个谨慎的实现,不要像代码那样执行数据:

while IFS= read -r -d '' chunk; do
  openssl rsa -pubin -noout -modulus <<<"$chunk"
done < <(jq -j '(.pubKey, "\u0000")' seq.json)
  • BashFAQ #1
  • 中详细记录了while read惯用语
  • 使用process substitution<(...)语法)是出于BashFAQ #24中所述的原因。
  • -d中使用read参数,在-j中使用jq参数,并且在JSON中使用"\u0000",则使用NUL分隔符来单独提取数据项。之所以使用它们,是因为NUL是唯一不能在C字符串中表示的字符。因此,它们可以用来表示C程序可以存储在字符串中的任何数据项之间的定界符。参见stedolan/jq#1271,了解jq中此功能的历史记录。

答案 1 :(得分:0)

您可以像在jq cannot use program as filter yet内那样在jq内完成此操作,

jq -j --slurp 'map(.pubKey) | join(">")' seq.json | xargs --delimiter=> -n1 --no-run-if-empty -i sh -c 'echo "{}" | openssl rsa -pubin -noout -modulus'

注意:

  1. 您的样本输入是多个对象而不是对象数组,因此使用--slurp。如果不是这种情况,则需要删除此标志。
  2. pubKey不能包含'>',因此我将其用作分隔符。假设您的数据来自可靠来源,并且不会破坏系统。