Reshaping loosely structured JSON (field names stored in array) - jq

I have a unique problem I have been struggling to get my head wrapped around. I have a bit of JSON from an API. The field names are actually stored in .headerData.methodNames and most of the values are stored in .lightValueObjects[].data.
{
"headerData": {
"objectTypeName": "device",
"methodNames": [
"name",
"accessIp",
"deviceType",
"version",
"discoverTime",
"discoverMethod",
"status",
"department",
"description",
"perfMonStatus",
"eventLogStatus",
"maintenance",
"location",
"agentStatus",
"policyName",
"policyId",
"agentType",
"templateIds",
"agentId",
"decommission",
"accountId",
"instanceId",
"agentVersion",
"parserName"
]
},
"lightValueObjects": [
{
"objectId": 17657,
"custId": 1,
"parentId": null,
"collectorId": null,
"data": [
"super",
"192.168.128.222",
"leader",
null,
1637092568000,
"LOG",
1,
"Super",
null,
"",
"Normal",
"",
null,
"",
"",
"",
null,
"",
null,
false,
"",
"",
null,
""
],
"extData": null,
"naturalId": "lead%2dsuper",
"aoSys": false
},
{
"objectId": 883252,
"custId": 1,
"parentId": null,
"collectorId": null,
"data": [
"fw01",
"192.168.128.1",
"fw",
"ANY",
1637098725000,
"LOG",
1,
"Super",
null,
"",
"Normal",
"",
null,
"",
"",
"",
null,
"",
null,
false,
"",
"",
null,
""
],
"extData": null,
"naturalId": "fw01",
"aoSys": false
}
],
"errCode": 0,
"errObj": null,
"dataType": "Device",
"totalCount": 0
}
The following code produces better output, but it's not quite perfect.
.headerData.methodNames as $header | [.lightValueObjects[].data] | map(
. as $o |
reduce .[] as $item({}; ($o | index($item)) as $index |
.[$header[$index]] = (if $item == "" then null else $item end))
)
[
{
"name": "super",
"accessIp": "192.168.128.222",
"deviceType": "leader",
"version": null,
"discoverTime": 1637092568000,
"discoverMethod": "LOG",
"status": 1,
"department": "Super",
"perfMonStatus": null,
"eventLogStatus": "Normal",
"decommission": false
},
{
"name": "fw01",
"accessIp": "192.168.128.1",
"deviceType": "fw",
"version": "ANY",
"discoverTime": 1637098725000,
"discoverMethod": "LOG",
"status": 1,
"department": "Super",
"description": null,
"perfMonStatus": null,
"eventLogStatus": "Normal",
"decommission": false
}
]
Current Problems
There should be 24 fields returned per device, but only 11 are being shown.
I have not been able to figure out how to merge the named values in .lightValueObjects to the final output.
Here is an example of what I am trying to make the output show, (To keep things simple, I am only showing 1 device)
[
{
"name": "super",
"accessIp": "192.168.128.222",
"deviceType": "leader",
"version": null,
"discoverTime": 1637092568000,
"discoverMethod": "LOG",
"status": 1,
"department": "Super",
"description": null,
"perfMonStatus": null,
"eventLogStatus": "Normal",
"maintenance": null,
"location": null,
"agentStatus": null,
"policyName": null,
"agentType": null,
"templateIds": null,
"agentId": null,
"decommission": false,
"accountId": null,
"instanceId": null,
"agentVersion": null,
"parserName": null,
"objectId": 17657,
"custId": 1,
"parentId": null,
"collectorId": null,
"extData": null,
"naturalId": "lead%2dsuper",
"aoSys": false
}
]
Any help would be GREATLY appreciated!!

I don't know if I got all your alignments right, but give this a try:
.headerData.methodNames as $header
| .lightValueObjects | map(
( [$header, .data]
| transpose
| map({(first): last})
| add
) + del(.data)
)
[
{
"name": "super",
"accessIp": "192.168.128.222",
"deviceType": "leader",
"version": null,
"discoverTime": 1637092568000,
"discoverMethod": "LOG",
"status": 1,
"department": "Super",
"description": null,
"perfMonStatus": "",
"eventLogStatus": "Normal",
"maintenance": "",
"location": null,
"agentStatus": "",
"policyName": "",
"policyId": "",
"agentType": null,
"templateIds": "",
"agentId": null,
"decommission": false,
"accountId": "",
"instanceId": "",
"agentVersion": null,
"parserName": "",
"objectId": 17657,
"custId": 1,
"parentId": null,
"collectorId": null,
"extData": null,
"naturalId": "lead%2dsuper",
"aoSys": false
},
{
"name": "fw01",
"accessIp": "192.168.128.1",
"deviceType": "fw",
"version": "ANY",
"discoverTime": 1637098725000,
"discoverMethod": "LOG",
"status": 1,
"department": "Super",
"description": null,
"perfMonStatus": "",
"eventLogStatus": "Normal",
"maintenance": "",
"location": null,
"agentStatus": "",
"policyName": "",
"policyId": "",
"agentType": null,
"templateIds": "",
"agentId": null,
"decommission": false,
"accountId": "",
"instanceId": "",
"agentVersion": null,
"parserName": "",
"objectId": 883252,
"custId": 1,
"parentId": null,
"collectorId": null,
"extData": null,
"naturalId": "fw01",
"aoSys": false
}
]
Demo
Edit: If you want to replace empty strings "" with null, as you did in your approach, replace last from my solution with either (last | select(. != "") // null) or, more explicitly, with (last | if . == "" then null else . end).

Related

Ansible: create a dictionary from a register.results var

i have the result variable ( see at the bottom ) from a task (modul community.general.proxmox_kvm) and i want create a new dictionary variable from the items that changed in the result variable.
The structure should look like this
vm_dict:
80001:
host_name: ansible-clone1
host_ip_address: 10.10.0.1
80002:
host_name: ansible-clone2
host_ip_address: 10.10.0.2
What is a good way to accomplish this ? I tryed it with set_fact and combine filter but i get stucked and was not able to put multible values. Also the changed status not worked as expected.
- name: Populate dict
set_fact:
_dict: "{{ _dict|default({}) | combine( {item.item.key: item.item.value.host_name} ) }}"
loop: "{{ provisioning_vm.results }}"
when: provisioning_vm.changed == true
I will be happy for some suggestions.
Here is the result variable ( type list )
TASK [provisioning_proxmox : print var provisioning_vm] *************************************************************
ok: [localhost] => {
"provisioning_vm": {
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"acpi": null,
"agent": null,
"api_host": "10.0.10.1:8006",
"api_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"api_token_id": null,
"api_token_secret": null,
"api_user": "ansible_admin#pve",
"args": null,
"autostart": null,
"balloon": null,
"bios": null,
"boot": null,
"bootdisk": null,
"cicustom": null,
"cipassword": null,
"citype": null,
"ciuser": null,
"clone": "arbitrary_template",
"cores": null,
"cpu": null,
"cpulimit": null,
"cpuunits": null,
"delete": null,
"description": null,
"digest": null,
"efidisk0": null,
"force": null,
"format": "raw",
"freeze": null,
"full": true,
"hostpci": null,
"hotplug": null,
"hugepages": null,
"ide": null,
"ipconfig": null,
"keyboard": null,
"kvm": null,
"localtime": null,
"lock": null,
"machine": null,
"memory": null,
"migrate_downtime": null,
"migrate_speed": null,
"name": "ansible-clone1.dev.test.com",
"nameservers": null,
"net": null,
"newid": 80001,
"node": "proxmox01",
"numa": null,
"numa_enabled": null,
"onboot": null,
"ostype": null,
"parallel": null,
"pool": null,
"protection": null,
"proxmox_default_behavior": "no_defaults",
"reboot": null,
"revert": null,
"sata": null,
"scsi": null,
"scsihw": null,
"searchdomains": null,
"serial": null,
"shares": null,
"skiplock": null,
"smbios": null,
"snapname": null,
"sockets": null,
"sshkeys": null,
"startdate": null,
"startup": null,
"state": "present",
"storage": "CEPH-DEV",
"tablet": null,
"tags": null,
"target": null,
"tdf": null,
"template": null,
"timeout": 400,
"update": false,
"validate_certs": false,
"vcpus": null,
"vga": null,
"virtio": null,
"vmid": 987654,
"watchdog": null
}
},
"item": {
"key": 80001,
"value": {
"host_ip_address": "10.10.0.1",
"host_name": "ansible-clone1.dev.test.com"
}
},
"msg": "VM with name <ansible-clone1.dev.test.com> already exists",
"vmid": 80001
},
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"acpi": null,
"agent": null,
"api_host": "10.0.10.1:8006",
"api_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"api_token_id": null,
"api_token_secret": null,
"api_user": "ansible_admin#pve",
"args": null,
"autostart": null,
"balloon": null,
"bios": null,
"boot": null,
"bootdisk": null,
"cicustom": null,
"cipassword": null,
"citype": null,
"ciuser": null,
"clone": "arbitrary_template",
"cores": null,
"cpu": null,
"cpulimit": null,
"cpuunits": null,
"delete": null,
"description": null,
"digest": null,
"efidisk0": null,
"force": null,
"format": "raw",
"freeze": null,
"full": true,
"hostpci": null,
"hotplug": null,
"hugepages": null,
"ide": null,
"ipconfig": null,
"keyboard": null,
"kvm": null,
"localtime": null,
"lock": null,
"machine": null,
"memory": null,
"migrate_downtime": null,
"migrate_speed": null,
"name": "ansible-clone2.dev.test.com",
"nameservers": null,
"net": null,
"newid": 80002,
"node": "proxmox01",
"numa": null,
"numa_enabled": null,
"onboot": null,
"ostype": null,
"parallel": null,
"pool": null,
"protection": null,
"proxmox_default_behavior": "no_defaults",
"reboot": null,
"revert": null,
"sata": null,
"scsi": null,
"scsihw": null,
"searchdomains": null,
"serial": null,
"shares": null,
"skiplock": null,
"smbios": null,
"snapname": null,
"sockets": null,
"sshkeys": null,
"startdate": null,
"startup": null,
"state": "present",
"storage": "CEPH-DEV",
"tablet": null,
"tags": null,
"target": null,
"tdf": null,
"template": null,
"timeout": 400,
"update": false,
"validate_certs": false,
"vcpus": null,
"vga": null,
"virtio": null,
"vmid": 987654,
"watchdog": null
}
},
"item": {
"key": 80002,
"value": {
"host_ip_address": "10.10.0.2",
"host_name": "ansible-clone2.dev.test.com"
}
},
"msg": "VM with name <ansible-clone2.dev.test.com> already exists",
"vmid": 80002
},
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"acpi": null,
"agent": null,
"api_host": "10.0.10.1:8006",
"api_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"api_token_id": null,
"api_token_secret": null,
"api_user": "ansible_admin#pve",
"args": null,
"autostart": null,
"balloon": null,
"bios": null,
"boot": null,
"bootdisk": null,
"cicustom": null,
"cipassword": null,
"citype": null,
"ciuser": null,
"clone": "arbitrary_template",
"cores": null,
"cpu": null,
"cpulimit": null,
"cpuunits": null,
"delete": null,
"description": null,
"digest": null,
"efidisk0": null,
"force": null,
"format": "raw",
"freeze": null,
"full": true,
"hostpci": null,
"hotplug": null,
"hugepages": null,
"ide": null,
"ipconfig": null,
"keyboard": null,
"kvm": null,
"localtime": null,
"lock": null,
"machine": null,
"memory": null,
"migrate_downtime": null,
"migrate_speed": null,
"name": "ansible-clone4.dev.test.com",
"nameservers": null,
"net": null,
"newid": 80004,
"node": "proxmox01",
"numa": null,
"numa_enabled": null,
"onboot": null,
"ostype": null,
"parallel": null,
"pool": null,
"protection": null,
"proxmox_default_behavior": "no_defaults",
"reboot": null,
"revert": null,
"sata": null,
"scsi": null,
"scsihw": null,
"searchdomains": null,
"serial": null,
"shares": null,
"skiplock": null,
"smbios": null,
"snapname": null,
"sockets": null,
"sshkeys": null,
"startdate": null,
"startup": null,
"state": "present",
"storage": "CEPH-DEV",
"tablet": null,
"tags": null,
"target": null,
"tdf": null,
"template": null,
"timeout": 400,
"update": false,
"validate_certs": false,
"vcpus": null,
"vga": null,
"virtio": null,
"vmid": 987654,
"watchdog": null
}
},
"item": {
"key": 80004,
"value": {
"host_ip_address": "10.10.10.4",
"host_name": "ansible-clone4.dev.test.com"
}
},
"msg": "VM with name <ansible-clone4.dev.test.com> already exists",
"vmid": 80004
}
],
"skipped": false
}
}
For example,
vm_dict: "{{ dict(provisioning_vm.results|
json_query('[].[item.key, item.value]')) }}"
gives
vm_dict:
80001:
host_ip_address: 10.10.0.1
host_name: ansible-clone1.dev.test.com
80002:
host_ip_address: 10.10.0.2
host_name: ansible-clone2.dev.test.com
80004:
host_ip_address: 10.10.10.4
host_name: ansible-clone4.dev.test.com
Optionally, the task below rejects changed items. Change the filter to selectattr if you want to select them
vm_dict: "{{ dict(provisioning_vm.results|
rejectattr('changed')|
json_query('[].[item.key, item.value]')) }}"

How to add row to ACF repeater field in Term

I have a taxonomy with an ACF repeater field. I am trying to add rows in a callback for a custom REST API endpoint and having no luck. The scheme for the field is:
{
"key": "field_5faa2bc09fe7b",
"label": "team",
"name": "team",
"type": "repeater",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"collapsed": "",
"min": 0,
"max": 10,
"layout": "table",
"button_label": "",
"sub_fields": [
{
"key": "field_5faa2bce9fe7c",
"label": "Role",
"name": "role",
"type": "post_object",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"post_type": [
"role"
],
"taxonomy": "",
"allow_null": 0,
"multiple": 0,
"return_format": "id",
"ui": 1
},
{
"key": "field_5faa2c0b9fe7d",
"label": "User",
"name": "user",
"type": "user",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"role": "",
"allow_null": 0,
"multiple": 0,
"return_format": "id"
}
]
}
I use the following to add a row to the field - and having no luck:
function wp_api_assign_internal_writer() {
register_rest_route( 'mynamespace/v1', 'assign_internal_writer/', array(
'methods' => 'POST',
'callback' => 'assign_internal_writer_callback',
));
}
function assign_internal_writer_callback( $request ) {
$parameters = $request->get_params();
$task = $parameters['task'];
$user = $parameters['user'];
$project_set = $parameters['project_set'];
if($task != '' && $user != '' && $project_set != '' ){
$row = array(
'field_5faa2bce9fe7c' => '268',
'field_5faa2c0b9fe7d' => $user
);
add_row('team', $row, $project_set);
return get_term_meta($project_set);
}else{
return 'Please supply the correct request parameters, Task ID and User ID';
}
}
Any idea what I am doing wrong? Does add row work only for Post and not Term....? I doubt thats it...
Based on your ACF field type i can only suggest to check if it actually expect the real object for the Wp_Post and for the Wp_User. Maybe try to convert your id's into objects and see if it works.
If that's not the issue please be more clear about what you mean with "had no luck". Does that mean you have fatal errors? no warning? no row inserted? ecc...

How do I create custom output object in Kusto

I have array like below as one of the properties for my object. I'd like to extract certain fields and return it still as array in output. For example I want only name and storageAccountType to be returned like below
Desired Output
[
{
"name": "Data",
"storageAccountType": "Standard_LRS"
},
{
"name": "Disk2",
"storageAccountType": "Standard_LRS"
}
]
Input Array
[
{
"name": "Data",
"createOption": "Attach",
"diskSizeGB": 10,
"managedDisk": {
"id": "/subscriptions/24ba3e4c-45e3-4d55-8132-6731cf25547f/resourceGroups/GREG/providers/Microsoft.Compute/disks/Data",
"storageAccountType": "Standard_LRS"
},
"caching": "None",
"toBeDetached": false,
"lun": 0
},
{
"name": "Disk2",
"createOption": "Attach",
"diskSizeGB": 10,
"managedDisk": {
"id": "/subscriptions/24ba3e4c-45e3-4d55-8132-6731cf25547f/resourceGroups/GREG/providers/Microsoft.Compute/disks/Disk2",
"storageAccountType": "Standard_LRS"
},
"caching": "None",
"toBeDetached": false,
"lun": 1
}
]
here's a direction you could follow (which assumes you actually needs to get back arrays and not to have each element in the array in its own row. if the latter is good, remove the rows with the comments (// *)
datatable(some_value:string, d:dynamic) // just a sample data set with 2 records
[
"hello", dynamic([
{
"name": "Data",
"createOption": "Attach",
"diskSizeGB": 10,
"managedDisk": {
"id": "/subscriptions/24ba3e4c-45e3-4d55-8132-6731cf25547f/resourceGroups/GREG/providers/Microsoft.Compute/disks/Data",
"storageAccountType": "Standard_LRS"
},
"caching": "None",
"toBeDetached": false,
"lun": 0
},
{
"name": "Disk2",
"createOption": "Attach",
"diskSizeGB": 10,
"managedDisk": {
"id": "/subscriptions/24ba3e4c-45e3-4d55-8132-6731cf25547f/resourceGroups/GREG/providers/Microsoft.Compute/disks/Disk2",
"storageAccountType": "Standard_LRS"
},
"caching": "None",
"toBeDetached": false,
"lun": 1
}
]), "world", dynamic([
{
"name": "Data3",
"createOption": "Attach",
"diskSizeGB": 10,
"managedDisk": {
"id": "/subscriptions/24ba3e4c-45e3-4d55-8132-6731cf25547f/resourceGroups/GREG/providers/Microsoft.Compute/disks/Data",
"storageAccountType": "Standard_LRS"
},
"caching": "None",
"toBeDetached": false,
"lun": 0
},
{
"name": "Disk23",
"createOption": "Attach",
"diskSizeGB": 10,
"managedDisk": {
"id": "/subscriptions/24ba3e4c-45e3-4d55-8132-6731cf25547f/resourceGroups/GREG/providers/Microsoft.Compute/disks/Disk2",
"storageAccountType": "Standard_LRS"
},
"caching": "None",
"toBeDetached": false,
"lun": 1
}
])
]
// --> answer starts here <--
| extend r = rand() // *
| mv-apply d on (
project d = pack("name", d.name, "storageAccountType", d.managedDisk.storageAccountType)
)
| summarize d = make_list(d) by r, some_value // *
| project-away r // *

WooCommerce hooks - Product update deliver variation objects instead of IDs

When receiving a product updated hook from WooCommerce, the payload contains a 'variations' array, which, however, only contains the IDs of the variations that belong to the updated product.
How can I send the actual variation objects along with the product updated payload, instead of only the IDs of the variation (this way, I wouldn't need to send another request to the variations resource of the REST API to fetch them).
Thanks!
You need to hook woocommerce_webhook_payload to build the payload. The details of the product variation are stored in variations_objs.
// Hook to the webhook build process and add your variations objects.
add_filter( 'woocommerce_webhook_payload', 'dolly_woocommerce_webhook_payload', 10, 4 );
function dolly_woocommerce_webhook_payload( $payload, $resource, $resource_id, $id ) {
// Remove the filter to eliminate the recursion calls.
remove_filter( 'woocommerce_webhook_payload', 'dolly_woocommerce_webhook_payload', 10 );
// Create a WC_Webhook class with the webhook id.
$wc_webhook = new WC_Webhook( $id );
// Bail early if the resource is not product.
if ( 'product' !== $resource ) {
return $payload;
}
// Bail early if the product type is not variable.
$product = new WC_Product( $resource_id );
if ( 'variable' === $product->get_type() ) {
return $payload;
}
// Build the payload of each product variation.
$variations = $payload['variations'];
foreach( $variations as $variation ) {
$variations_objs[] = $wc_webhook->build_payload( $variation );
}
// Add the varitions to the payload.
$payload['variations_objs'] = $variations_objs;
// Add the filter again and return the payload.
add_filter( 'woocommerce_webhook_payload', 'dolly_woocommerce_webhook_payload', 10, 4 );
return $payload;
}
Here is the data sent by the webhooks.
{
"id" : 94,
"name" : "Nepali Shirt",
"slug" : "nepali-shirt",
"permalink" : "http://online-users.test/product/nepali-shirt/",
"date_created" : "2019-07-14T05:12:52",
"date_created_gmt" : "2019-07-14T05:12:52",
"date_modified" : "2019-07-18T07:52:36",
"date_modified_gmt" : "2019-07-18T07:52:36",
"type" : "variable",
"status" : "publish",
"featured" : false,
"catalog_visibility" : "visible",
"description" : "<p>hello tamang hhh jjjjj sfsfsd hllk ljlkjkl jljk ljlkjkl kjlkjlk jlkj dgdfg jkl ljlk sdfdsf sfsd sfdds</p>\n",
"short_description" : "",
"sku" : "",
"price" : "205",
"regular_price" : "",
"sale_price" : "",
"date_on_sale_from" : null,
"date_on_sale_from_gmt": null,
"date_on_sale_to" : null,
"date_on_sale_to_gmt" : null,
"price_html" : "<span class=\"woocommerce-Price-amount amount\"><span class=\"woocommerce-Price-currencySymbol\">£</span>205.00</span> – <span class=\"woocommerce-Price-amount amount\"><span class=\"woocommerce-Price-currencySymbol\">£</span>500.00</span>",
"on_sale" : false,
"purchasable" : true,
"total_sales" : 0,
"virtual" : false,
"downloadable" : false,
"downloads" : [],
"download_limit" : -1,
"download_expiry" : -1,
"external_url" : "",
"button_text" : "",
"tax_status" : "taxable",
"tax_class" : "",
"manage_stock" : false,
"stock_quantity" : null,
"in_stock" : true,
"backorders" : "no",
"backorders_allowed" : false,
"backordered" : false,
"sold_individually" : false,
"weight" : "",
"dimensions" : {
"length": "",
"width" : "",
"height": ""
},
"shipping_required": true,
"shipping_taxable" : true,
"shipping_class" : "",
"shipping_class_id": 0,
"reviews_allowed" : true,
"average_rating" : "0.00",
"rating_count" : 0,
"related_ids" : [
82,
80
],
"upsell_ids" : [],
"cross_sell_ids": [],
"parent_id" : 0,
"purchase_note" : "",
"categories" : [
{
"id" : 15,
"name": "Uncategorized",
"slug": "uncategorized"
}
],
"tags" : [],
"images": [
{
"id" : 0,
"date_created" : "2019-07-18T07:53:30",
"date_created_gmt" : "2019-07-18T07:53:30",
"date_modified" : "2019-07-18T07:53:30",
"date_modified_gmt": "2019-07-18T07:53:30",
"src" : "http://online-users.test/wp-content/uploads/woocommerce-placeholder-324x324.png",
"name" : "Placeholder",
"alt" : "Placeholder",
"position" : 0
}
],
"attributes": [
{
"id" : 1,
"name" : "Color",
"position" : 0,
"visible" : true,
"variation": true,
"options" : [
"Blue",
"Gray",
"Red"
]
}
],
"default_attributes": [
{
"id" : 1,
"name" : "Color",
"option": "blue"
}
],
"variations": [
96,
97,
98
],
"grouped_products": [],
"menu_order" : 0,
"meta_data" : [
{
"id" : 1103,
"key" : "pageview",
"value": "1"
}
],
"store": {
"id" : 1,
"name" : "admin",
"shop_name": "WordPress Biratnagar",
"url" : "http://online-users.test/store/admin/",
"address" : {
"street_1": "Haatkhola",
"street_2": "",
"city" : "Biratnagar",
"zip" : "977",
"country" : "NP",
"state" : "BAG"
}
},
"variations_objs": [
{
"id" : 96,
"name" : "Nepali Shirt - Blue",
"slug" : "nepali-shirt-blue",
"permalink" : "http://online-users.test/product/nepali-shirt/?attribute_pa_color=blue",
"date_created" : "2019-07-14T05:12:12",
"date_created_gmt" : "2019-07-14T05:12:12",
"date_modified" : "2019-07-18T06:52:07",
"date_modified_gmt" : "2019-07-18T06:52:07",
"type" : "variation",
"status" : "publish",
"featured" : false,
"catalog_visibility" : "visible",
"description" : "",
"short_description" : "",
"sku" : "",
"price" : "205",
"regular_price" : "205",
"sale_price" : "",
"date_on_sale_from" : null,
"date_on_sale_from_gmt": null,
"date_on_sale_to" : null,
"date_on_sale_to_gmt" : null,
"price_html" : "<span class=\"woocommerce-Price-amount amount\"><span class=\"woocommerce-Price-currencySymbol\">£</span>205.00</span>",
"on_sale" : false,
"purchasable" : true,
"total_sales" : "0",
"virtual" : false,
"downloadable" : false,
"downloads" : [],
"download_limit" : -1,
"download_expiry" : -1,
"external_url" : "",
"button_text" : "",
"tax_status" : "taxable",
"tax_class" : "",
"manage_stock" : false,
"stock_quantity" : null,
"in_stock" : true,
"backorders" : "no",
"backorders_allowed" : false,
"backordered" : false,
"sold_individually" : false,
"weight" : "",
"dimensions" : {
"length": "",
"width" : "",
"height": ""
},
"shipping_required": true,
"shipping_taxable" : true,
"shipping_class" : "",
"shipping_class_id": 0,
"reviews_allowed" : false,
"average_rating" : "0.00",
"rating_count" : 0,
"related_ids" : [],
"upsell_ids" : [],
"cross_sell_ids" : [],
"parent_id" : 94,
"purchase_note" : "",
"categories" : [],
"tags" : [],
"images" : [
{
"id" : 0,
"date_created" : "2019-07-18T07:54:12",
"date_created_gmt" : "2019-07-18T07:54:12",
"date_modified" : "2019-07-18T07:54:12",
"date_modified_gmt": "2019-07-18T07:54:12",
"src" : "http://online-users.test/wp-content/uploads/woocommerce-placeholder-324x324.png",
"name" : "Placeholder",
"alt" : "Placeholder",
"position" : 0
}
],
"attributes": [
{
"id" : 1,
"name" : "Color",
"option": "Blue"
}
],
"default_attributes": [],
"variations" : [],
"grouped_products" : [],
"menu_order" : 1,
"meta_data" : [],
"store" : {
"id" : 1,
"name" : "admin",
"shop_name": "WordPress Biratnagar",
"url" : "http://online-users.test/store/admin/",
"address" : {
"street_1": "Haatkhola",
"street_2": "",
"city" : "Biratnagar",
"zip" : "977",
"country" : "NP",
"state" : "BAG"
}
}
},
{
"id" : 97,
"name" : "Nepali Shirt - Gray",
"slug" : "nepali-shirt-gray",
"permalink" : "http://online-users.test/product/nepali-shirt/?attribute_pa_color=gray",
"date_created" : "2019-07-14T05:12:13",
"date_created_gmt" : "2019-07-14T05:12:13",
"date_modified" : "2019-07-14T05:12:44",
"date_modified_gmt" : "2019-07-14T05:12:44",
"type" : "variation",
"status" : "publish",
"featured" : false,
"catalog_visibility": "visible",
"description" : "",
"short_description": "",
"sku": "",
"price": "300",
"regular_price": "300",
"sale_price": "",
"date_on_sale_from": null,
"date_on_sale_from_gmt": null,
"date_on_sale_to": null,
"date_on_sale_to_gmt": null,
"price_html": "<span class=\"woocommerce-Price-amount amount\"><span class=\"woocommerce-Price-currencySymbol\">£</span>300.00</span>",
"on_sale": false,
"purchasable": true,
"total_sales": "0",
"virtual": false,
"downloadable": false,
"downloads": [],
"download_limit": -1,
"download_expiry": -1,
"external_url": "",
"button_text": "",
"tax_status": "taxable",
"tax_class": "",
"manage_stock": false,
"stock_quantity": null,
"in_stock": true,
"backorders": "no",
"backorders_allowed": false,
"backordered": false,
"sold_individually": false,
"weight": "",
"dimensions": {
"length": "",
"width": "",
"height": ""
},
"shipping_required": true,
"shipping_taxable": true,
"shipping_class": "",
"shipping_class_id": 0,
"reviews_allowed": false,
"average_rating": "0.00",
"rating_count": 0,
"related_ids": [],
"upsell_ids": [],
"cross_sell_ids": [],
"parent_id": 94,
"purchase_note": "",
"categories": [],
"tags": [],
"images": [
{
"id": 0,
"date_created": "2019-07-18T07:54:13",
"date_created_gmt": "2019-07-18T07:54:13",
"date_modified": "2019-07-18T07:54:13",
"date_modified_gmt": "2019-07-18T07:54:13",
"src": "http://online-users.test/wp-content/uploads/woocommerce-placeholder-324x324.png",
"name": "Placeholder",
"alt": "Placeholder",
"position": 0
}
],
"attributes": [
{
"id": 1,
"name": "Color",
"option": "Gray"
}
],
"default_attributes": [],
"variations": [],
"grouped_products": [],
"menu_order": 2,
"meta_data": [],
"store": {
"id": 1,
"name": "admin",
"shop_name": "WordPress Biratnagar",
"url": "http://online-users.test/store/admin/",
"address": {
"street_1": "Haatkhola",
"street_2": "",
"city": "Biratnagar",
"zip": "977",
"country": "NP",
"state": "BAG"
}
}
},
{
"id": 98,
"name": "Nepali Shirt - Red",
"slug": "nepali-shirt-red",
"permalink": "http://online-users.test/product/nepali-shirt/?attribute_pa_color=red",
"date_created": "2019-07-14T05:12:14",
"date_created_gmt": "2019-07-14T05:12:14",
"date_modified": "2019-07-14T05:42:04",
"date_modified_gmt": "2019-07-14T05:42:04",
"type": "variation",
"status": "publish",
"featured": false,
"catalog_visibility": "visible",
"description": "",
"short_description": "",
"sku": "",
"price": "500",
"regular_price": "500",
"sale_price": "",
"date_on_sale_from": null,
"date_on_sale_from_gmt": null,
"date_on_sale_to": null,
"date_on_sale_to_gmt": null,
"price_html": "<span class=\"woocommerce-Price-amount amount\"><span class=\"woocommerce-Price-currencySymbol\">£</span>500.00</span>",
"on_sale": false,
"purchasable": true,
"total_sales": "0",
"virtual": false,
"downloadable": false,
"downloads": [],
"download_limit": -1,
"download_expiry": -1,
"external_url": "",
"button_text": "",
"tax_status": "taxable",
"tax_class": "",
"manage_stock": false,
"stock_quantity": null,
"in_stock": true,
"backorders": "no",
"backorders_allowed": false,
"backordered": false,
"sold_individually": false,
"weight": "",
"dimensions": {
"length": "",
"width": "",
"height": ""
},
"shipping_required": true,
"shipping_taxable": true,
"shipping_class": "",
"shipping_class_id": 0,
"reviews_allowed": false,
"average_rating": "0.00",
"rating_count": 0,
"related_ids": [],
"upsell_ids": [],
"cross_sell_ids": [],
"parent_id": 94,
"purchase_note": "",
"categories": [],
"tags": [],
"images": [
{
"id": 0,
"date_created": "2019-07-18T07:54:14",
"date_created_gmt": "2019-07-18T07:54:14",
"date_modified": "2019-07-18T07:54:14",
"date_modified_gmt": "2019-07-18T07:54:14",
"src": "http://online-users.test/wp-content/uploads/woocommerce-placeholder-324x324.png",
"name": "Placeholder",
"alt": "Placeholder",
"position": 0
}
],
"attributes": [
{
"id": 1,
"name": "Color",
"option": "Red"
}
],
"default_attributes": [],
"variations": [],
"grouped_products": [],
"menu_order": 3,
"meta_data": [],
"store": {
"id": 1,
"name": "admin",
"shop_name": "WordPress Biratnagar",
"url": "http://online-users.test/store/admin/",
"address": {
"street_1": "Haatkhola",
"street_2": "",
"city": "Biratnagar",
"zip": "977",
"country": "NP",
"state": "BAG"
}
}
}
]
}

How to produce a single line output of a record with jq

I have the following JSON
{
"guid": "dce38b4b-9989-42d2-b6bd-702645e344cf",
"name": "dev",
"apps": [
{
"guid": "5d5498cb-a885-4242-a55a-d7d286a1cf48",
"urls": [
"nodered.cloudfoundry.org"
],
"routes": [
{
"guid": "aca4d04b-f99d-4b43-afaa-82ab41afa07c",
"host": "nodered-test",
"port": null,
"path": "",
"domain": {
"guid": "f4b90d7e-2cd3-4d30-b200-f28bbaf6be20",
"name": "cloudfoundry.org"
}
}
],
"service_count": 1,
"service_names": [
"nodered-test-cloudantNoSQLDB"
],
"running_instances": 1,
"name": "perik-nodered-test",
"production": false,
"space_guid": "dce38b4b-9989-42d2-b6bd-702645e344cf",
"stack_guid": "ac91d31a-86a3-453b-babf-8d49c9d763fc",
"buildpack": null,
"detected_buildpack": "SDK for Node.js(TM) (ibm-node.js-6.13.0, buildpack-v3.20-20180403-1426)",
"detected_buildpack_guid": "33e9e82f-8846-4362-a60a-92964285a31e",
"environment_json": {},
"memory": 256,
"instances": 1,
"disk_quota": 1024,
"state": "STARTED",
"version": "8c8c97a0-bc2e-424c-a0a3-d64704feb634",
"command": null,
"console": false,
"debug": null,
"staging_task_id": "539f460c-e4d2-49f9-b5e5-9f4fd31a8370",
"package_state": "STAGED",
"health_check_type": "port",
"health_check_timeout": null,
"health_check_http_endpoint": null,
"staging_failed_reason": null,
"staging_failed_description": null,
"diego": true,
"docker_image": null,
"package_updated_at": "2018-04-10T17:32:06Z",
"detected_start_command": "./vendor/initial_startup.rb",
"enable_ssh": true,
"ports": null
},
{
"guid": "4089ce19-19fb-467b-8876-3635819d5d91",
"urls": [
"nodered.cloudfoundry.org"
],
"routes": [
{
"guid": "b79988d8-5ac5-455d-8fdd-00bc208dd2bc",
"host": "NodeRedTestApp",
"port": null,
"path": "",
"domain": {
"guid": "f4b90d7e-2cd3-4d30-b200-f28bbaf6be20",
"name": "cloudfoundry.org"
}
}
],
"service_count": 1,
"service_names": [
"NodeRedTestApp-cloudantNoSQLDB"
],
"running_instances": 1,
"name": "perik-NodeRedTestApp",
"production": false,
"space_guid": "dce38b4b-9989-42d2-b6bd-702645e344cf",
"stack_guid": "ac91d31a-86a3-453b-babf-8d49c9d763fc",
"buildpack": null,
"detected_buildpack": "SDK for Node.js(TM) (ibm-node.js-6.13.0, buildpack-v3.20-20180403-1426)",
"detected_buildpack_guid": "33e9e82f-8846-4362-a60a-92964285a31e",
"environment_json": {},
"memory": 256,
"instances": 1,
"disk_quota": 1024,
"state": "STARTED",
"version": "17175bdb-df93-4745-9a17-cf214fe05976",
"command": null,
"console": false,
"debug": null,
"staging_task_id": "5c74633a-25db-4adf-9eb8-09454a70be52",
"package_state": "STAGED",
"health_check_type": "port",
"health_check_timeout": null,
"health_check_http_endpoint": null,
"staging_failed_reason": null,
"staging_failed_description": null,
"diego": true,
"docker_image": null,
"package_updated_at": "2018-04-09T21:23:27Z",
"detected_start_command": "./vendor/initial_startup.rb",
"enable_ssh": true,
"ports": null
}
]
}
and getting the following values using
cat test.json | jq -r '.apps[].routes[].host, .apps[].state, .apps[].package_updated_at' which produces the following output
nodered-test
NodeRedTestApp
STARTED
STARTED
2018-04-10T17:32:06Z
2018-04-09T21:23:27Z
How can I get the output as
nodered-test STARTED 2018-04-10T17:32:06Z
NodeRedTestApp STARTED 2018-04-09T21:23:27Z
So that I can assign it to a bash script array.
jq solution:
jq -r '.apps[] | [.routes[].host, .state, .package_updated_at] | join(" ")' test.json
The output:
nodered-test STARTED 2018-04-10T17:32:06Z
NodeRedTestApp STARTED 2018-04-09T21:23:27Z

Resources