本文主要講解在OOS如何對任務中的值進行篩選,任務中值的篩選主要依賴模版中兩個常見字段,一個是ValueSelector,另一個是PropertySelector,且這兩個字段必須配合jq表達式使用。那麼接下來就分別講下jq是什麼,兩個篩選字段何時需要定義、在哪定義和作用,以及各場景下jq表達式使用的分析。
jq介紹
jq 是一個開源的數據處理工具,它可處理JSON格式的數據,比如按照您指定的jq表達式,篩選出JSON中你想要的部分。篩選時,jq把JSON格式的數據作爲input,並根據指定的jq表達式進行篩選,然後返回一個output。jq有很多靈活的使用方法,詳見後附的jq語法手冊。
OOS中的篩選字段
先說下OOS任務中值的篩選目的,無非兩種,一種是篩出期待的結果,並將其賦值給某個參數,供其他任務使用該參數;另一種則是篩選出期待的結果,在任務中將結果值與預先指定的值進行比較,用來檢查某種條件。所以OOS中有兩個用來篩選的字段,分別是ValueSelector和PropertySelector,前者用在給參數賦值前,後者用在檢查某個條件前。
當任務有具體Outputs時,需要在Outputs中定義ValueSelector字段,該字段用來篩選任務動作返回的值,並且將篩選結果賦值給Outputs輸出的參數。具體講,如任務的動作爲API類動作,則動作返回值即任務調用API後返回的JSON值;若任務的動作爲事件觸發器,則動作返回值爲觸發器監控事件發生的JSON消息通知體。篩選方式是jq把動作返回值作爲輸入參數,通過字段的jq表達式進行篩選,篩選結果作爲任務的Outputs輸出參數值。
當任務的動作爲ACS::WaitFor 或ACS::CheckFor時,需要在任務的Properties部分定義PropertySelector字段,
該字段用來篩選任務調用API返回的JSON值,篩選方式是jq把API返回的JSON作爲輸入參數,並通過字段的jq表達式進行篩選,最後OOS將篩選結果與Properties中的DesiredValues或NotDesiredValues字段內包含的值進行比較,比較結果作爲任務等待或判斷的參考,進而執行後面的邏輯。
jq在OOS中的使用
ValueSelector
場景1
FormatVersion: OOS-2019-06-01
Description: Adds backend servers by specifying tag.
Parameters:
loadBalancerId:
Description: The ID of the SLB instance.
Type: String
AllowedPattern: lb-[A-Za-z0-9]*
MaxLength: 30
MinLength: 1
tagKey:
Description: The specific tag key.
Type: String
MinLength: 1
tagValue:
Description: The specific tag value.
Type: String
MaxLength: 30
MinLength: 1
OOSAssumeRole:
Description: The RAM role to be assumed by OOS.
Type: String
Default: OOSServiceRole
RamRole: '{{ OOSAssumeRole }}'
Tasks:
- Name: describeRunningInstancesByTag
Action: ACS::ExecuteApi
Description: Views the ECS instances by specifying tag.
Properties:
Service: ECS
API: DescribeInstances
Parameters:
Status: Running
Tags:
- Key: '{{ tagKey }}'
Value: '{{ tagValue }}'
Outputs:
instanceIds:
Type: List
ValueSelector: .Instances.Instance[].InstanceId
我們來看下上面的模版,請直接看Tasks部分的describeRunningInstancesByTag任務,該任務是有具體Outputs的,其定義了輸出名稱爲instanceIds
的參數,參數Type爲List,同時也定義了ValueSelector字段,並且該字段的jq表達式爲.Instances.Instance[].InstanceId
。
就如Outputs中參數名 instanceIds
字面意思,其表示輸出API返回結果中所有ECS實例ID,那麼該任務調用的API是DescribeInstances,API返回的JSON結果樣例如下。結合此JSON樣例,我們看下在.Instances.Instance[].InstanceId
作用下,instanceIds最終返回值的獲取過程。首先篩選出JSON中Key爲Instances
的結果,然後對結果繼續篩選,獲取Key爲Instance
的結果,該結果是一個數組,此時又對所得結果進行迭代,並將每個迭代結果中Key爲InstanceId
的值以List類型進行返回,於是得到最終返回值["id-001","id-002"],即'{{describeRunningInstancesByTag.instanceIds}}'的值爲["id-001","id-002"]'。
API調用返回樣例(JSON)
{
"PageNumber":"1",
"TotalCount":"1",
"PageSize":"10",
"RequestId":"14A07460-EBE7-47CA-9757-12CC4761D47A",
"Instances":{
"Instance":[
{
"ImageId":"centos6u5_64_20G_aliaegis_20150130.vhd",
"InnerIpAddress":{
"IpAddress":[
"10.170.XX.XXX"
]
},
"InstanceId":"id-001",
"EipAddress":{},
"InternetMaxBandwidthIn":"-1",
"ZoneId":"cn-shenzhen-a",
"InstanceNetworkType":"classic",
"PublicIpAddress":{
"IpAddress":[
"120.25.XX.XXX"
]
},
"InternetChargeType":"PayByTraffic",
"HostName":"iZ94t3s0j***",
"InstanceType":"ecs.s2.large",
"SerialNumber":"51d1353b-22bf-4567-a176-8b3e12e43135",
"IoOptimized":"false",
"CreationTime":"2015-07-27T07:08Z",
"Status":"Running",
"VpcAttributes":{
"PrivateIpAddress":{
"IpAddress":[]
}
},
"InternetMaxBandwidthOut":"1",
"SecurityGroupIds":{
"SecurityGroupId":[
"sg-94kd0c***"
]
},
"RegionId":"cn-shenzhen",
"OperationLocks":{
"LockReason":[]
},
"InstanceChargeType":"PostPaid",
"ExpiredTime":"2011-09-08T16:00Z",
"InstanceName":"FinanceJoshua1"
},
{
"ImageId":"centos6u5_64_20G_aliaegis_20150130.vhd",
"InnerIpAddress":{
"IpAddress":[
"10.170.XX.XXX"
]
},
"InstanceId":"id-002",
"EipAddress":{},
"InternetMaxBandwidthIn":"-1",
"ZoneId":"cn-shenzhen-a",
"InstanceNetworkType":"classic",
"PublicIpAddress":{
"IpAddress":[
"120.25.XX.XXX"
]
},
"InternetChargeType":"PayByTraffic",
"HostName":"iZ94t3s0j***",
"InstanceType":"ecs.s2.large",
"SerialNumber":"51d1353b-22bf-4567-a176-8b3e12e43135",
"IoOptimized":"false",
"CreationTime":"2015-07-27T07:08Z",
"Status":"Running",
"VpcAttributes":{
"PrivateIpAddress":{
"IpAddress":[]
}
},
"InternetMaxBandwidthOut":"1",
"SecurityGroupIds":{
"SecurityGroupId":[
"sg-94kd0c***"
]
},
"RegionId":"cn-shenzhen",
"OperationLocks":{
"LockReason":[]
},
"InstanceChargeType":"PostPaid",
"ExpiredTime":"2011-09-08T16:00Z",
"InstanceName":"FinanceJoshua2"
}
]
}
}
場景2
FormatVersion: OOS-2019-06-01
Description: Resets system disks to its initial state by specifying instance IDs.
The specified ECS instances must be in stopped status.
Parameters:
instanceIds:
Description: The ID list of the ECS instance.
Type: List
maxErrors:
Description: The maximum number of errors allowed during task execution.
Type: Number
Default: 0
concurrency:
Description: Concurrency ratio of task execution.
Type: Number
Default: 1
OOSAssumeRole:
Description: The RAM role to be assumed by OOS.
Type: String
Default: OOSServiceRole
RamRole: '{{ OOSAssumeRole }}'
Tasks:
- Name: checkInstanceReady
Action: ACS::CheckFor
Description: Checks ECS instances is in the stopped status.
Properties:
Service: ECS
API: DescribeInstances
Parameters:
InstanceIds:
- '{{ ACS::TaskLoopItem }}'
DesiredValues:
- Stopped
PropertySelector: Instances.Instance[].Status
Loop:
MaxErrors: '{{ maxErrors }}'
Concurrency: '{{ concurrency }}'
Items: '{{ instanceIds }}'
- Name: querySystemDisks
Action: ACS::ExecuteAPI
Description: Views system disk of the ECS instance.
Properties:
Service: ECS
API: DescribeDisks
Parameters:
InstanceId: '{{ ACS::TaskLoopItem }}'
DiskType: system
Loop:
Items: '{{ instanceIds }}'
Outputs:
diskIds:
AggregateType: Fn::ListJoin
AggregateField: diskId
Outputs:
diskId:
Type: String
ValueSelector: .Disks.Disk[].DiskId
我們來看下上面的模版,請直接看Tasks部分的querySystemDisks任務,該任務是有具體Outputs的,其定義了輸出名稱爲 diskId
的參數,參數Type爲 String
,同時也定義了ValueSelector字段,並且該字段的jq表達式爲 .Disks.Disk[].DiskId
。
就如Outputs中參數名diskId字面意思,其表示輸出API返回結果中的磁盤ID,那麼該任務調用的API是DescribeDisks,API返回的JSON結果樣例如下。結合此JSON樣例,我們看下在 .Disks.Disk[].DiskId 作用下,diskId最終返回值的獲取過程。首先篩選出JSON中Key爲Disks的結果,然後對結果繼續篩選,獲取Key爲Disk的結果,該結果是一個數組,此時又對所得結果進行迭代,並將每個迭代結果中Key爲DiskId的值以String類型進行返回,於是得到最終返回值 'd-28m5zb1sz
',即'{{querySystemDisks.diskId}}'的值爲'd-28m5zb1sz
'。
上面可能有疑問,該場景的jq表達式和場景一的類似,且處理的數據結構也一樣,爲何此處最後只返回了一個String,而不像場景一返回了List。簡單解釋下,其實返回參數的Type是不同的,當Type爲List時,OOS最後會把返回的一個或多個結果裝到List中作爲最終結果返回;當Type爲String時,OOS最後會取返回的一個或多個結果中的第一個來作爲最終結果。
API調用返回樣例(JSON)
{
"PageNumber":1,
"TotalCount":9,
"PageSize":2,
"RequestId":"ACD9BBB0-A9D1-46D7-9630-B7A69889E110",
"Disks":{
"Disk":[
{
"ImageId":"",
"Description":"",
"Device":"",
"ProductCode":"",
"Portable":true,
"DetachedTime":"2014-07-23T08:28:48Z",
"Type":"data",
"InstanceId":"",
"ZoneId":"cn-qingdao-b",
"EnableAutoSnapshot":false,
"DiskName":"",
"AttachedTime":"2014-07-23T07:47:35Z",
"SourceSnapshotId":"",
"CreationTime":"2014-07-23T02:44:07Z",
"Status":"Available",
"DeleteAutoSnapshot":true,
"Category":"cloud",
"RegionId":"cn-qingdao",
"DeleteWithInstance":false,
"OperationLocks":{
"OperationLock":[]
},
"DiskId":"d-28m5zb1sz",
"Size":5
},
{
"ImageId":"",
"Description":"",
"Device":"",
"ProductCode":"",
"Portable":true,
"DetachedTime":"",
"Type":"data",
"InstanceId":"",
"ZoneId":"cn-qingdao-b",
"EnableAutoSnapshot":false,
"DiskName":"",
"AttachedTime":"",
"SourceSnapshotId":"",
"CreationTime":"2014-07-23T02:44:06Z",
"Status":"Available",
"DeleteAutoSnapshot":true,
"Category":"cloud",
"RegionId":"cn-qingdao",
"DeleteWithInstance":false,
"OperationLocks":{
"OperationLock":[]
},
"DiskId":"d-28zfrmo13",
"Size":5
}
]
}
}
場景3
---
FormatVersion: OOS-2019-06-01
Description: Start ECS instance when instance is stopped.
Parameters:
accessToken:
Description: Dingtalk access_token to be notified.
Type: String
AllowedPattern: '[A-Za-z0-9]*'
regionId:
Description: The Region Id of SLB and Instance.
Type: String
MinLength: 1
MaxLength: 30
OOSAssumeRole:
Description: The RAM role to be assumed by OOS.
Type: String
Default: OOSServiceRole
loadBalancerId:
Description: The ID of the SLB instance.
Type: String
AllowedPattern: lb-[A-Za-z0-9]*
MaxLength: 30
MinLength: 1
RamRole: '{{OOSAssumeRole}}'
Tasks:
- Name: whenInstanceStopped
Action: 'ACS::EventTrigger'
Properties:
Product: ECS
Name:
- 'Instance:StateChange'
Level:
- INFO
Content:
state:
- Stopped
Outputs:
instanceId:
ValueSelector: content.resourceId
Type: String
- Name: checkNeedRemoveOrNot
Action: ACS::CheckFor
Description: check the interrupted Instance is being added on SLB or Not.
OnError: ACS::END
OnSuccess: ACS::NEXT
Properties:
Service: SLB
API: DescribeLoadBalancerAttribute
Parameters:
RegionId: '{{ regionId }}'
LoadBalancerId: '{{ loadBalancerId }}'
DesiredValues:
- "{{whenInstanceStopped.instanceId}}"
PropertySelector: 'BackendServers.BackendServer[].ServerId|select(.=="{{whenInstanceStopped.instanceId}}")'
- Name: queryLoadBalancerAttribute
Action: ACS::ExecuteApi
Description: Views ECS instances to backend servers.
Properties:
Service: SLB
API: DescribeLoadBalancerAttribute
Parameters:
RegionId: '{{ regionId }}'
LoadBalancerId: '{{ loadBalancerId }}'
Outputs:
removeOrNot:
Type: List
ValueSelector: 'BackendServers.BackendServer[]|select(.ServerId=="{{whenInstanceStopped.instanceId}}")'
backendServersToRemove:
Type: List
ValueSelector: 'BackendServers.BackendServer[]|select(.ServerId=="{{whenInstanceStopped.instanceId}}")|del(.Type)'
我們來看下上面的模版,先看Tasks部分的whenInstanceStopped
任務,它會輸出一個名爲 instanceId
的參數,關於這個任務知道這些就夠了。然後看Tasks部分的 queryLoadBalancerAttribute
任務,該任務是有具體Outputs的,比如其定義了輸出名稱爲 backendServersToRemove
的參數,參數Type爲 List
,同時也在參數中定義了ValueSelector字段,並且該字段的jq表達式爲 .BackendServers.BackendServer[]|
select(.ServerId=="{{whenInstanceStopped.instanceId}}")|del(.Type)
,表達式好長,沒關係,我們分析完,您就會發現它很簡單。
就如Outputs中參數名backendServersToRemove字面意思,其表示輸出API返回結果中的後端服務器列表,那麼該任務調用的API是DescribeLoadBalancerAttribute,API返回的JSON結果樣例如下。結合此JSON樣例,我們看下在這個很長的jq表達式作用下,backendServersToRemove最終返回值的獲取過程。首先篩選出JSON中Key爲BackendServers
的結果,然後對結果繼續篩選,獲取Key爲BackendServer
的結果,該結果是一個數組,此時對所得結果進行迭代,然後我們看到的管道符 |
,也就是把迭代獲取的所有結果交到下一段操作,操作是,將每個迭代結果中Key爲ServerId
的值與whenInstanceStopped
任務輸出參數instanceId
的值進行比較。如果比較結果是相等,則拿到該ServerId
所在的這個Mapping,並將該Mapping中Key爲的Type
的key-val對剔除,再把該Mapping返回;如果比較結果爲不相等,則忽略掉這個ServerId
所在的Mapping。比較完後做下整理把所有返回的Mapping放在一個List中返回。假如whenInstanceStopped.instanceId
值是"i-bp1234",得到最終返回值則爲 [{"ServerId":"i-bp1234","Weight":100 }]
,即'{{queryLoadBalancerAttribute.backendServersToRemove}}'的值爲[{"ServerId":"i-bp1234","Weight":100 }]
。
API調用返回樣例(JSON)
{
"CreateTimeStamp":1541679713000,
"RegionIdAlias":"cn-hangzhou",
"HasReservedInfo":"false",
"BackendServers":{
"BackendServer":[
{
"ServerId":"i-bpxccv123456jo7v",
"Weight":100,
"Type":"ecs"
}
]
},
"ListenerPorts":{
"ListenerPort":[]
},
"VSwitchId":"vsw-bp1ccv123456jk9bmlj",
"InternetChargeType":"paybytraffic",
"VpcId":"vpc-bp1ccv123456j1qc5cm",
"SlaveZoneId":"cn-hangzhou-d",
"NetworkType":"vpc",
"LoadBalancerSpec":"slb.s2.small",
"ListenerPortsAndProtocol":{
"ListenerPortAndProtocol":[]
},
"PayType":"PayOnDemand",
"Bandwidth":5120,
"LoadBalancerName":"abc1",
"ResourceGroupId":"rg-acfmxazb4ph6aiy",
"AddressIPVersion":"ipv4",
"LoadBalancerId":"lb-bp23456jfuca5",
"EndTimeStamp":32493801600000,
"MasterZoneId":"cn-hangzhou-b",
"ListenerPortsAndProtocal":{
"ListenerPortAndProtocal":[]
},
"Address":"192.168.0.6",
"RegionId":"cn-hangzhou",
"RequestId":"35D745B3-1567-4855-9EF1-F5CED3C1670C",
"CreateTime":"2018-11-08T12:21:53Z",
"EndTime":"2999-09-08T16:00:00Z",
"AddressType":"intranet",
"LoadBalancerStatus":"active"
}
PropertySelector
場景1(CheckFor)
FormatVersion: OOS-2019-06-01
Description: Creates a disk and attaches a data disk to an ECS instance.
Parameters:
diskName:
Description: The name of the disk.
Type: String
zoneId:
Description: The zone ID that is available in the specified region.
Type: String
diskCategory:
Description: The category of the data disk.
Type: String
instanceId:
Description: Creates a subscription disk and the system automatically attaches
it to a subscription instance with the InstanceId you specified.
Type: String
AllowedPattern: i-[A-Za-z0-9]*
MinLength: 1
MaxLength: 30
size:
Description: The size of the disk.
Type: String
Tasks:
- Name: checkInstanceReady
Action: ACS::CheckFor
Description: Checks whether the ECS instance status is running or stopped.
Properties:
Service: ECS
API: DescribeInstances
Parameters:
InstanceIds:
- '{{ instanceId }}'
DesiredValues:
- Running
- Stopped
PropertySelector: .Instances.Instance[].Status
我們來看下上面的模版,請直接看Tasks部分的checkInstanceReady任務,該任務的動作是 ACS::CheckFor
,其Properties部分定義了DesiredValues的值爲 ['Running','Stopped']
,同時也定義了PropertySelector字段,並且該字段的jq表達式爲 .Instances.Instance[].Status
。
該任務中,DesiredValues和PropertySelector兩個字段會被聯合起來,用來驗證指定的條件即['Running','Stopped']
,驗證過程爲先把API返回的JSON結果通過jq表達式篩選處理,再檢查處理得到的篩選結果是否在DesiredValues字段的List中。如果在List中,則該任務執行結果爲Success,否則該任務執行結果爲Failed。
那麼該任務調用的API是DescribeInstances,API返回的JSON結果樣例如下。結合此JSON樣例,我們看下在 .Instances.Instance[].Status
作用下,最終返回值的獲取過程。首先篩選出JSON中Key爲Instances
的結果,然後對結果繼續篩選,獲取Key爲Instance
的結果,該結果是一個數組,此時對所得結果進行迭代,迭代獲取數組中的第一個元素,並將該元素中Key爲 Status
的值作爲與指定的條件比較的值,即檢查'Running'是否在['Running','Stopped']
中。
API調用返回樣例(JSON)
{
"PageNumber":"1",
"TotalCount":"1",
"PageSize":"10",
"RequestId":"14A07460-EBE7-47CA-9757-12CC4761D47A",
"Instances":{
"Instance":[
{
"ImageId":"centos6u5_64_20G_aliaegis_20150130.vhd",
"InnerIpAddress":{
"IpAddress":[
"10.170.XX.XXX"
]
},
"InstanceId":"id-001",
"EipAddress":{},
"InternetMaxBandwidthIn":"-1",
"ZoneId":"cn-shenzhen-a",
"InstanceNetworkType":"classic",
"PublicIpAddress":{
"IpAddress":[
"120.25.XX.XXX"
]
},
"InternetChargeType":"PayByTraffic",
"HostName":"iZ94t3s0j***",
"InstanceType":"ecs.s2.large",
"SerialNumber":"51d1353b-22bf-4567-a176-8b3e12e43135",
"IoOptimized":"false",
"CreationTime":"2015-07-27T07:08Z",
"Status":"Running",
"VpcAttributes":{
"PrivateIpAddress":{
"IpAddress":[]
}
},
"InternetMaxBandwidthOut":"1",
"SecurityGroupIds":{
"SecurityGroupId":[
"sg-94kd0c***"
]
},
"RegionId":"cn-shenzhen",
"OperationLocks":{
"LockReason":[]
},
"InstanceChargeType":"PostPaid",
"ExpiredTime":"2011-09-08T16:00Z",
"InstanceName":"FinanceJoshua1"
},
{
"ImageId":"centos6u5_64_20G_aliaegis_20150130.vhd",
"InnerIpAddress":{
"IpAddress":[
"10.170.XX.XXX"
]
},
"InstanceId":"id-002",
"EipAddress":{},
"InternetMaxBandwidthIn":"-1",
"ZoneId":"cn-shenzhen-a",
"InstanceNetworkType":"classic",
"PublicIpAddress":{
"IpAddress":[
"120.25.XX.XXX"
]
},
"InternetChargeType":"PayByTraffic",
"HostName":"iZ94t3s0j***",
"InstanceType":"ecs.s2.large",
"SerialNumber":"51d1353b-22bf-4567-a176-8b3e12e43135",
"IoOptimized":"false",
"CreationTime":"2015-07-27T07:08Z",
"Status":"Running",
"VpcAttributes":{
"PrivateIpAddress":{
"IpAddress":[]
}
},
"InternetMaxBandwidthOut":"1",
"SecurityGroupIds":{
"SecurityGroupId":[
"sg-94kd0c***"
]
},
"RegionId":"cn-shenzhen",
"OperationLocks":{
"LockReason":[]
},
"InstanceChargeType":"PostPaid",
"ExpiredTime":"2011-09-08T16:00Z",
"InstanceName":"FinanceJoshua2"
}
]
}
}
場景2(WaitFor)
FormatVersion: OOS-2019-06-01
Description: Creates a custom image.
Parameters:
imageName:
Description: The image name.
Type: String
instanceId:
Description: The ID of the instance.
Type: String
AllowedPattern: i-[A-Za-z0-9]*
MinLength: 1
MaxLength: 30
Tasks:
- Name: checkInstanceReady
Action: ACS::CheckFor
Description: Checks whether the ECS instance status is running or stopped.
Properties:
Service: ECS
API: DescribeInstances
Parameters:
InstanceIds:
- '{{ instanceId }}'
DesiredValues:
- Running
- Stopped
PropertySelector: Instances.Instance[].Status
- Name: createImage
Action: ACS::ExecuteAPI
Description: Creates a custom image.
Properties:
Service: ECS
API: CreateImage
Parameters:
ImageName: '{{ imageName }}'
InstanceId: '{{ instanceId }}'
Outputs:
imageId:
Type: String
ValueSelector: ImageId
- Name: untilImageReady
Action: ACS::WaitFor
Description: Waits for the image to be available.
Properties:
Service: ECS
API: DescribeImages
Parameters:
ImageId: '{{ createImage.imageId }}'
DesiredValues:
- Available
PropertySelector: .Images.Image[].Status
我們來看下上面的模版,請直接看Tasks部分的untilImageReady任務,該任務的動作是 ACS::WaitFor
,其Properties部分定義了DesiredValues的值爲 ['Available']
,同時也定義了PropertySelector字段,並且該字段的jq表達式爲 .Images.Image[].Status
。
該任務中,DesiredValues和PropertySelector兩個字段會被聯合起來,用來驗證指定的條件即['Available']
,驗證過程爲先把API返回的JSON結果通過jq表達式篩選處理,再檢查處理得到的篩選結果是否在DesiredValues字段的List中。如果在List中,則該任務不再繼續等待,並結束該任務向下執行;否則該任務會隔段時間再次調用API,並檢查結果是否滿足條件,直至條件滿足或超出最大檢查次數。
那麼該任務調用的API是DescribeImages,API返回的JSON結果樣例如下。結合此JSON樣例,我們看下在 .Images.Image[].Status
作用下,最終返回值的獲取過程。首先篩選出JSON中Key爲Images
的結果,然後對結果繼續篩選,獲取Key爲Image
的結果,該結果是一個數組,此時對所得結果進行迭代,迭代獲取數組中的第一個元素,並將該元素中Key爲 Status
的值作爲與指定的條件比較的值,即檢查'Available
'是否在['Available']
中。
API調用返回樣例(JSON)
{
"PageNumber":1,
"TotalCount":24,
"PageSize":1,
"RequestId":"49CBCED4-C9B9-4851-BEB5-8FB5E5169E30",
"RegionId":"cn-hangzhou",
"Images":{
"Image":[
{
"ImageId":"suse11sp3_64_20G_aliaegis_20150428.vhd",
"OSType":"linux",
"Architecture":"x86_64",
"OSName":"SUSE Linux Enterprise Server 11 SP3 64位",
"DiskDeviceMappings":{
"DiskDeviceMapping":[
{
"Device":"/dev/xvda",
"Size":"20"
}
]
},
"ImageOwnerAlias":"system",
"Progress":"100%",
"Usage":"instance",
"CreationTime":"2015-05-06T09:01:32Z",
"Status":"Available",
"ImageVersion":"1",
"ImageName":"suse11sp3_64_20G_aliaegis_20150428.vhd",
"IsCopied":false,
"IsSubscribed":false,
"Platform":"SUSE",
"Size":20
}
]
}
}
jq語法手冊
基礎用法
通過Key篩選
jq表達式:".foo"
input:
{"foo": 42, "bar": "less interesting data"}
通過Index篩選
jq表達式:".[0]"
input:
[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]
output:
{
"name": "JSON",
"good": true
}
通過Iterator篩選
jq表達式:".[]"
input:
["hello","world"]
output:
"hello"
"world"
jq表達式:".[]"
input:
[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]
output:
{
"name": "JSON",
"good": true
}
{
"name": "XML",
"good": false
}
通過Pipe("|")篩選
jq表達式:".[]|.name"
input:
[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]
output:
"JSON"
"XML"
構造Array
jq表達式:"[.user, .projects[]]"
input:
{"user":"stedolan", "projects": ["jq", "wikiflow"]}
output:
[
"stedolan",
"jq",
"wikiflow"
]
構造Mapping
jq表達式:"{user, title: .titles}"
input:
{"user":"stedolan","titles":["JQ Primer", "More JQ"]}
output:
{
"user": "stedolan",
"title": [
"JQ Primer",
"More JQ"
]
}
jq表達式:"{(.user): .titles}"
input:
{"user":"stedolan","titles":["JQ Primer", "More JQ"]}
output:
{
"stedolan": [
"JQ Primer",
"More JQ"
]
}
內建操作符和函數
Addition(+)
jq表達式:".a + 1"
input:
{"a": 7}
output:
8
jq表達式:".a + .b"
input:
{"a": [1,2], "b": [3,4]}
output:
[
1,
2,
3,
4
]
Subtraction(-)
jq表達式:". - ["xml", "yaml"]"
input:
["xml", "yaml", "json"]
output:
[
"json"
]
Length
jq表達式:"[.[]| length]"
input:
[[1,2], "string", {"a":2}, null]
output:
[
2,
6,
1,
0
]
Keys
jq表達式:"keys"
input:
{"abc": 1, "abcd": 2, "Foo": 3}
output:
[
"Foo",
"abc",
"abcd"
]
In
jq表達式:'.[] | in({"foo": 42})'
input:
["foo", "bar"]
output:
true
false
map
jq表達式:"map(.+1)"
input:
[1,2,3]
output:
[
2,
3,
4
]
map_values
jq表達式:"map_values(.+1)"
input:
{"a": 1, "b": 2, "c": 3}
output:
{
"a": 2,
"b": 3,
"c": 4
}
del
jq表達式:"del(.foo)"
input:
{"foo": 42, "bar": 9001, "baz": 42}
output:
{
"bar": 9001,
"baz": 42
}
select
jq表達式:'.[] | select(.id == "second")'
input:
[{"id": "first", "val": 1}, {"id": "second", "val": 2}]
output:
{
"id": "second",
"val": 2
}
jq表達式:"map(select(. >= 2))"
input:
[1,5,3,0,7]
output:
[
5,
3,
7
]
any
jq表達式:"any"
input:
[true, false]
output:
true
jq表達式:"any"
input:
[false, false]
output:
false
all
jq表達式:"all"
input:
[true, false]
output:
false
jq表達式:"all"
input:
[true, true]
output:
true
jq表達式:"all"
input:
[]
output:
true
jq表達式:"all"
input:
[]
output:
true
min、max
jq表達式:"min"
input:
[5,4,2,7]
output:
2
sort、sort_by
jq表達式:"sort"
input:
[8,3,null,6]
output:
[
null,
3,
6,
8
]
jq表達式:"sort_by(.foo)"
input:
[{"foo":4, "bar":10}, {"foo":3, "bar":100}, {"foo":2, "bar":1}]
output:
[
{
"foo": 2,
"bar": 1
},
{
"foo": 3,
"bar": 100
},
{
"foo": 4,
"bar": 10
}
]
index
jq表達式:'index(", ")'
input:
"a,b, cd, efg, hijk"
output:
3
split
jq表達式:'split(", ")'
input:
"a, b,c,d, e, "
output:
[
"a",
"b,c,d",
"e",
""
]
join
jq表達式:'join(", ")'
input:
["a","b,c,d","e"]
output:
"a, b,c,d, e"
jq表達式:'join(" ")'
input:
["a",1,2.3,true,null,false]
output:
"a 1 2.3 true false"
條件判斷
if-then-else
jq表達式:
'if . == 0 then "zero"elif . == 1 then "one"else "many"end'
input:
2
output:
"many"
>, <,>=, <=,==,!=
jq表達式:
'.<5'
input:
2
output:
true
jq表達式: '.==5'
input:
2
output:
false
高級用法
變量
jq表達式:".bar as $x | .foo | . + $x"
input:
{"foo":10, "bar":200}
output:
210
jq表達式:". as $i|[(.*2|. as $i| $i), $i]"
input:
5
output:
[
10,
5
]
自定義函數
jq表達式:"def addvalue(f): . + [f]; map(addvalue(.[0]))"
input:
[[1,2],[10,20]]
output:
[
[
1,
2,
1
],
[
10,
20,
10
]
]
jq表達式:"def addvalue(f): f as $x | map(. + $x); addvalue(.[0])"
input:
[[1,2],[10,20]]
output:
[
[
1,
2,
1,
2
],
[
10,
20,
1,
2
]
]