Как передать каждый вывод фильтра jq во внешнюю команду? - PullRequest
0 голосов
/ 01 апреля 2019

У меня большой файл с последовательностью 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 ]

2 голосов
/ 01 апреля 2019

Реализация, которая старается не выполнять данные, так как код может выглядеть следующим образом:

while IFS= read -r -d '' chunk; do
  openssl rsa -pubin -noout -modulus <<<"$chunk"
done < <(jq -j '(.pubKey, "\u0000")' seq.json)
  • Идиома while read подробно описана в BashFAQ # 1
  • Использование процесса подстановки (синтаксис <(...)) по причинам, описанным в BashFAQ # 24 .
  • Использование -dаргумент read, аргумент -j jq и использование "\u0000" внутри JSON использует разделители NUL для разделения извлеченных элементов данных.Они используются, потому что NUL являются единственным символом, который не может быть представлен внутри строк C;таким образом, они могут использоваться для представления разделителей между любыми элементами данных, которые программа C может хранить в строке.См. stedolan / jq # 1271 для истории этой функции в jq.
0 голосов
/ 01 апреля 2019

Вместо того, чтобы делать это в jq, поскольку 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 не может содержать «>», поэтому я использовал его в качестве разделителя.Это предполагает, что ваши данные поступают из надежного источника и не взорвут вашу систему.
...