首页 > 解决方案 > 将多个 jq 调用合并为一个

问题描述

我正在解析一个 JSON 文件,并将其分配给我稍后测试的 shell 变量,如果它不为空,并在其之上采取相应的操作。

我正在使用以下 jq 命令执行此操作:

 proxy_host=`jq -r .proxy_host <<< $line`
 proxy_port=`jq -r .proxy_port <<< $line`
 query_string=`jq -r .query_string <<< $line`
 realip_remote_addr=`jq -r .realip_remote_addr <<< $line`
 realpath_root=`jq -r .realpath_root <<< $line`
 request_body=`jq -r .request_body <<< $line`
 request_id=`jq -r .request_id <<< $line`
 request_method=`jq -r .request_method <<< $line`
 request_uri=`jq -r .request_uri <<< $line`
 scheme=`jq -r .scheme <<< $line`
 ssl_protocol=`jq -r .ssl_protocol <<< $line`
 ssl_ciphers=`jq -r .ssl_ciphers <<< $line`
 ssl_client_cert=`jq -r .ssl_client_cert <<< $line`
 ssl_client_fingerprint=`jq -r .ssl_client_fingerprint <<< $line`
 ssl_client_i_dn=`jq -r .ssl_client_i_dn <<< $line`
 ssl_client_raw_cert=`jq -r .ssl_client_raw_cert <<< $line`
 ssl_client_s_dn=`jq -r .ssl_client_s_dn <<< $line`
 ssl_client_serial=`jq -r .ssl_client_serial <<< $line`
 ssl_client_v_end=`jq -r .ssl_client_v_end <<< $line`
 ssl_client_v_remain=`jq -r .ssl_client_v_remain <<< $line`
 ssl_client_v_start=`jq -r .ssl_client_v_start <<< $line`
 ssl_client_verify=`jq -r .ssl_client_verify <<< $line`
 ssl_session_id=`jq -r .ssl_session_id <<< $line`
 tcpinfo_rtt=`jq -r .tcpinfo_rtt <<< $line`
 uri=`jq -r .uri <<< $line`

我的json:

{
  "host": "www.example.com",
  "hostname": "localhost",
  "proxy_add_x_forwarded_for": "127.0.0.1",
  "proxy_host": "",
  "proxy_port": "",
  "query_string": "",
  "realip_remote_addr": "8.1.2.3",
  "realpath_root": "/var/www/",
  "request_body": "",
  "request_id": "78e7cc17c207fc683992bae956150c4d",
  "request_method": "GET",
  "request_uri": "/",
  "scheme": "https",
  "server_name": "www.localhost.com",
  "ssl_protocol": "TLSv1.2",
  "ssl_ciphers": "AES128-GCM-SHA256:AES128-SHA:AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:0x000a:0x00ff",
  "ssl_client_cert": "",
  "ssl_client_fingerprint": "",
  "ssl_client_i_dn": "",
  "ssl_client_raw_cert": "",
  "ssl_client_s_dn": "",
  "ssl_client_serial": "",
  "ssl_client_v_end": "",
  "ssl_client_v_remain": "",
  "ssl_client_v_start": "",
  "ssl_client_verify": "NONE",
  "ssl_session_id": "3e10c1253816aa4b3ea80df403e752fadaa1c6e532febd25e288acb4f5735617",
  "tcpinfo_rtt": "11142",
  "uri": "/index.html"
}

我不想使用 awk 之类的 shell 工具来访问这些字段。有没有办法使用 jq 和 bash 来简化这个,而不是让 30 个独立的 jq 调用来完成这个?

标签: jsonbashjq

解决方案


您显然没有对jq. 只需执行一次即可转储所有键/值对并在单独的 shell 变量中读取它们

#!/usr/bin/env bash

while IFS= read -r line; do
    declare "$line"
done< <(jq -r 'to_entries[] | [.key,.value] | join("=")' json)

现在,您可以从命令行打印与 JSON 键中的变量同名的变量。要处理可以包含文字换行符的更健壮的 JSON 字符串,请使用空分隔符 ( "\u0000") 发出 JSON 输出并将read其返回。


推荐阅读