以下命令通过调用jq 4次来更新AWS Route 53 JSON模板中的4个元素:
cat x.json | jq '.ChangeBatch.Changes[].Action = "UPSERT"'|\
jq '.ChangeBatch.Changes[].ResourceRecordSet.Name = "host.domain"'|\
jq '.ChangeBatch.Changes[].ResourceRecordSet.Type = "A"'|\
jq '.ChangeBatch.Changes[].ResourceRecordSet.ResourceRecords[].TTL ="300"'\|
jq '.ChangeBatch.Changes[].ResourceRecordSet.ResourceRecords[].Value ="10.120.0.1"'
产生以下正确输出:
{
"HostedZoneId": "",
"ChangeBatch": {
"Comment": "",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "host.domain",
"Type": "A",
"SetIdentifier": "",
"Weight": 0,
"Region": "",
"GeoLocation": {
"ContinentCode": "",
"CountryCode": "",
"SubdivisionCode": ""
},
"Failover": "",
"TTL": 0,
"ResourceRecords": [
{
"Value": "10.120.0.1",
"TTL": "300"
}
有没有办法通过一次调用jq来更新所有4个字段?
答案 0 :(得分:0)
你可以管道每个调用的过滤器,你应该得到相同的结果。
$ jq '.ChangeBatch.Changes[].Action = "UPSERT"
| .ChangeBatch.Changes[].ResourceRecordSet.Name = "host.domain"
| .ChangeBatch.Changes[].ResourceRecordSet.Type = "A"
| .ChangeBatch.Changes[].ResourceRecordSet.ResourceRecords[].TTL ="300"
| .ChangeBatch.Changes[].ResourceRecordSet.ResourceRecords[].Value ="10.120.0.1"' x.json
但是,只要选择要更新的对象,就会有很多重复。您可以通过将对象与要合并的值与要设置的值合并来更新多个值。
$ jq '.ChangeBatch.Changes[] *= {
Action: "UPSERT",
ResourceRecordSet: {
Name: "host.domain",
Type: "A",
ResourceRecords: [
{
TTL: "300",
Value: "10.120.0.1"
}
]
}
}' x.json
但是,合并的方式有效,只有对象以递归方式合并。数组必须手动合并。因此,如果您想保留数组中的项目(如果超过1),您必须将其调整为:
$ jq '.ChangeBatch.Changes[] |= . * {
Action: "UPSERT",
ResourceRecordSet: {
Name: "host.domain",
Type: "A",
ResourceRecords: .ResourceRecordSet.ResourceRecords | map(
. * {
TTL: "300",
Value: "10.120.0.1"
}
)
}
}' x.json
答案 1 :(得分:0)
由于|=
的强大功能,以下相当简洁的过滤器应该能够直接完成工作:
.ChangeBatch.Changes[] |=
( .Action = "UPSERT"
| .ResourceRecordSet.Name = "host.domain"
| .ResourceRecordSet.Type = "A"
| .ResourceRecordSet.ResourceRecords[].TTL ="300"
| .ResourceRecordSet.ResourceRecords[].Value ="10.120.0.1"
)