使用jq将bash变量插入json

时间:2018-09-10 07:14:23

标签: json bash templates jq

我试图用增加的计数器填充JSON模板以生成巨大的样本数据集:

#!/bin/bash
for ((counter=1 ; counter<2 ;counter++ ))
do
  NUMBER=${counter}
  JSON=$(cat template.json | jq --arg NUMBER "$NUMBER" '.')
  echo $JSON
  #aws dynamodb batch-write-item --request-items "${JSON}"
done

我的template.json如下:

{
"My_Table":[{
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_A"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_A"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_A"},"name":{ ...        
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_B"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_B"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_B"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_C"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_C"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_D"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_E"},"name":{ ...
}]

}

我能否获得将bash变量插入JSON模板的任何线索?我猜我在这里使用jq的操作不正确:

JSON=$(cat template.json | jq --arg NUMBER "$NUMBER" '.')

编辑 我想要的输出:

{
"My_Table":[{
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_A"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_A"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_A"},"name":{ ...        
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_B"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_B"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_B"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_C"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_C"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_D"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_E"},"name":{ ...
}]

}

2 个答案:

答案 0 :(得分:1)

不幸的是,这个问题的几个部分不太有意义,但是我相信以下内容应该可以帮助您。

首先,我假设您的模板是有效的JSON:

{
    "My_Table": [
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_A"},"name":0}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_A"},"name":1}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_A"},"name":2}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_B"},"name":0}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_B"},"name":1}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_B"},"name":2}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_C"},"name":0}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_D"},"name":1}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_E"},"name":0}}}
  ]
}

第二,我假设您想要的结果与显示的内容大致相同,而不是如上所述,但是编写了以下内容,因此您可以轻松地使代码适应所描述的问题。具体地说,封装了进行替换的功能 在以下定义中:

def resolve(s; value):
  .My_Table |= map(.PutRequest.Item.type.S |= 
     sub("-" + s + "-"; "-" + (value|tostring) + "-" ));

这是使用sub编写的,其第一个参数必须是正则表达式。因此,要生成将“ $ NUMBER”替换为“ 1”的所需输出,可以这样写:

resolve("\\$NUMBER"; 1)

由于我不确定您的bash代码段应该做什么,因此,我建议您可以在jq中使用迭代来实现所需的结果,而不是使用bash迭代。

答案 1 :(得分:1)

如果模板打算与jq一起使用,则应将其更改为可以正常工作,而不是试图强制jq与不合格的输入一起工作。

{
    "My_Table":[{
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_A"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_A"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_A"},"name":{ ...        
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_B"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_B"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_B"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_C"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_C"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_D"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_E"},"name":{ ...
    }]
}

现在,类似您的原始尝试的内容将正确运行。 (将模板命名为template.jq,以强调它实际上不是有效的JSON。)

for ((counter=1 ; counter<2 ;counter++ ))
do
  JSON=$(jq -n -f template.jq --arg NUMBER "$counter")
  echo "$JSON"
  #aws dynamodb batch-write-item --request-items "${JSON}"
done