如何传递bash变量并使用jq生成动态JSON?

时间:2019-02-08 06:07:11

标签: arrays json bash variables jq

我有一堆bash var,我想将其转换为具有特定格式的JSON。我在将它们作为jq的参数传递给我时遇到了麻烦,并且摸不着头脑如何在jq本身内循环遍历2个数组。也许我应该先手动将这两个数组转换为JSON,然后再通过--argjson将该JSON传递给jq?

这是我到目前为止写的内容。

#!/usr/bin/env bash                                                                                                                                                                                                                       

#example data                                                                                                                                                                                                                             
_assetPair=BTCUSD
_version=0.9.1
_median=103.96
_medianHex="000000000000000000000000000000000000000000000005a2bc1d32419c0000"
_time=1549524531
_timeHex="000000000000000000000000000000000000000000000000000000005c5bde33"
_hash="db035aa02562167d23f657bb6f1030ba962d476f18a51c5c651b6b4b0"
_signature="51cd021f3c3edf1600aafaa81e366cd14543125dd7ec4c1da91765b0e632cfd313a3b8a291153262531e7027163ffe1239ddc9cc42815ddfcf70404a6cb5f2d71b"

#the size of the two below arrays is always equal but not known ahead of time                                                                                                                                                             
#unsure how to pass/use these in jq                                                                                                                                                                                                       
#if I pass in the elements I won't know which handle to call them with in jq                                                                                                                                                              
#maybe need some transpose magic here                                                                                                                                                                                                     
validSources=()
validPrices=()
validSources+=( "Bitfinex" "Poloniex" "Coinbase" )
validPrices+=( "104.61" "102.88" "103.96")

#Create jq input argument list                                                                                                                                                                                                            
_jqArgs=()
_jqArgs=( "--arg assetPair $_assetPair" "--arg version $_version" "--arg median $_median" "--arg median0x $_medianHex" "--arg time $_time" "--arg time0x $_timeHex" "--arg hash ${_hash:2}" "--arg signature ${_signature:2}" )
for index in ${!validSources[*]}; do
    _jqArgs+=( --arg "${validSources[index]}" "${validPrices[index]}" )
done

#sanity check                                                                                                                                                                                                                             
echo "${_jqArgs[@]}"

#generate json                                                                                                                                                                                                                            
jq -n "${_jqArgs[@]}" '{assetPair: $assetPair, version: $version, median: $median | tonumber, medianHex: $medianHex, time: $time | tonumber, timeHex: $timeHex, hash: $hash, signature: $signature}'

运行上面的脚本时,这是我得到的错误输出。

bash-5.0$ ./test.sh
--arg assetPair BTCUSD --arg version 0.9.1 --arg median 103.96 --arg median0x 000000000000000000000000000000000000000000000005a2bc1d32419c0000 --arg time 1549524531 --arg time0x 000000000000000000000000000000000000000000000000000000005c5bde33 --arg hash 035aa02562167d23f657bb6f1030ba962d476f18a51c5c651b6b4b0 --arg signature cd021f3c3edf1600aafaa81e366cd14543125dd7ec4c1da91765b0e632cfd313a3b8a291153262531e7027163ffe1239ddc9cc42815ddfcf70404a6cb5f2d71b --arg Bitfinex 104.61 --arg Poloniex 102.88 --arg Coinbase 103.96
jq: Unknown option --arg assetPair BTCUSD

在将其分配给jqArgs中的assetPair时,我曾尝试在BTCUSD周围添加转义的双引号,但返回的错误相同。

我期望这样的输出:

{
   "assetPair": "BTCUSD",
   "version": "0.9.1",
   "median": 103.96,
   "medianHex: "000000000000000000000000000000000000000000000005a2bc1d32419c0000",
   "time": 1549524531,
   "timeHex": "000000000000000000000000000000000000000000000000000000005c5bde33",
   "hash": "db035aa02562167d23f657bb6f1030ba962d476f18a51c5c651b6b4b0",
   "signature": "51cd021f3c3edf1600aafaa81e366cd14543125dd7ec4c1da91765b0e632cfd313a3b8a291153262531e7027163ffe1239ddc9cc42815ddfcf70404a6cb5f2d71b",
   "sources": {
      "Bitfinex": "104.61",
      "Coinbase: "103.96",
      "Poloniex": "102.88"
   }
}

1 个答案:

答案 0 :(得分:2)

以下调整足以使您的脚本正常运行:

  1. 修复名称不一致

    median0x =>中位数十六进制 time0x => timeHex

  2. 更改调用(引号)

    jq -n $ {_ jqArgs [@]} ...

处理bash数组

关于bash数组,我建议在您的情况下分别阅读它们,例如使用以下所示的技术:

jq -nc --argjson vs "$(printf '%s\n' "${validSources[@]}" | jq -nR '[inputs]')" '$vs'

使用您的数据,将产生:

["Bitfinex","Poloniex","Coinbase"]

构造.sources

然后,您可以使用$ vs和类似获得的$ vp来以.sources的形式构造所需的对象,例如遵循以下原则:

[$vs, $vp] | transpose | map({(.[0]): .[1]}) | add