Extract part of the string elements in an array using jq - json

I'm trying to extract part of the string in elements of an array, and create a new array with these extractions.
[
"local/binaries/app-2.21.0.tar.gz",
"local/binaries/app-2.20.0.tar.gz",
"local/binaries/app-2.19.1.tar.gz",
"local/binaries/app-2.19.0.tar.gz",
"local/binaries/app-2.18.0.tar.gz"
]
Desired output
[
"app-2.21.0",
"app-2.20.0",
"app-2.19.1",
"app-2.19.0",
"app-2.18.0"
]

You can use jq's capture function with regular expressions.
jq '[.[] | capture("(?<captured>app-[0-9]+\\.[0-9]+\\.[0-9]+)") | .[]]'
Try it out on jq playground.
Documentation: https://stedolan.github.io/jq/manual/#RegularexpressionsPCRE

Related

jq - Looping through json and concatenate the output to single string

I was currently learning the usage of jq. I have a json file and I am able to loop through and filter out the values I need from the json. However, I am running into issue when I try to combine the output into single string instead of having the output in multiple lines.
File svcs.json:
[
{
"name": "svc-A",
"run" : "True"
},
{
"name": "svc-B",
"run" : "False"
},
{
"name": "svc-C",
"run" : "True"
}
]
I was using the jq to filter to output the service names with run value as True
jq -r '.[] | select(.run=="True") | .name ' svcs.json
I was getting the output as follows:
svc-A
svc-C
I was looking to get the output as single string separated by commas.
Expected Output:
"svc-A,svc-C"
I tried to using join, but was unable to get it to work so far.
The .[] expression explodes the array into a stream of its elements. You'll need to collect the transformed stream (the names) back into an array. Then you can use the #csv filter for the final output
$ jq -r '[ .[] | select(.run=="True") | .name ] | #csv' svcs.json
"svc-A","svc-C"
But here's where map comes in handy to operate on an array's elements:
$ jq -r 'map(select(.run=="True") | .name) | #csv' svcs.json
"svc-A","svc-C"
Keep the array using map instead of decomposing it with .[], then join with a glue string:
jq -r 'map(select(.run=="True") | .name) | join(",")' svcs.json
svc-A,svc-C
Demo
If your goal is to create a CSV output, there is a special #csv command taking care of quoting, escaping etc.
jq -r 'map(select(.run=="True") | .name) | #csv' svcs.json
"svc-A","svc-C"
Demo

String Manipulation within a JSON array using jq

I am writing a bash script and I am looking to replace a character within a JSON field in a JSON array. In this case, I am trying to change the "." (period) character to a "-" (hyphen) in the name field. I am using jq to parse my JSON. Any tips on how I can achieve this will greatly help. Thank you!
Bash Script so far:
RAW=$(curl ${URL})
function manip() {
# Function for string manipulation.
}
echo "${RAW}" | jq '.data | .[].name = $manip' # Unable to make a function call in there.
Sample JSON:
[
{"id":"1","name":"a.a"},
{"id":"2","name":"b.b"},
{"id":"3","name":"c.c"}
]
Expected Output:
[
{"id":"1","name":"a-a"},
{"id":"2","name":"b-b"},
{"id":"3","name":"c-c"}
]
To replace a dot with a dash, use the sub function:
jq '.[].name |= sub("\\."; "-")' file.json

How to use regex to match a JSON value with jq?

My JSON data:
[
"delivery_1b36940ef75c49a8864d8cb3ea6a3a9f",
"toPayBtn_10021",
"item_fdd0772d0dd74dea93033761ca14e781",
"item_4f1a3f6fd3afdb940be008a0d325f9ad",
"delivery_d69dc5e9df971c9b2b1736c2231cb4a9",
"orderTotal_1",
"address_BILLING#1",
"delivery_185e36d98d5e4cc1808e59e44df8c71c",
"voucherInput_1",
"address_DELIVERY#1",
"item_864e1a7daf2aa424cbcb2251d55abda9",
"item_913196f953cbe8cfc2851c8fa9498607"
]
I want to match toPayBtn_10021 but the number after toPayBtn_ is dynamic, it can be toPayBtn_10 toPayBtn_2 toPayBtn_847 etc...
I have tried
jq '.toPayBtn_*'
but it doesn't work, how do I fix it ?
.[] | select( test("^toPayBtn_") )

How do I print the keyS from a json object using JQ

Sample input
{
“event_timestamp”: “2016-03-16 13:19:53 UTC”,
“query”: “Plagiarism”,
“search_session_id”: “3605862756e95d26ac180",
“version”: “0.0.2",
“other”: “{\“client_timestamp\“:1458134393.932,\"ios_page_index\":3}“,
“action”: “HIT_BOUNCE”
}
{
“event_timestamp”: “2016-03-16 13:19:53 UTC”,
“query”: “Plagiarism”,
“search_session_id”: “3605862756e95d26ac180",
“version”: “0.0.2",
“other”:“{\“client_timestamp\“:1458134393.932,\"ios_page_index\":3,\"ios_index_path_row\":1}“,
“action”: “HIT_BOUNCE”
}
I'd like to output the unique key name in "other" field
"client_timestamp,
ios_page_index,
ios_index_path_row "
Tried the following command but doesn't work so far
cat sampleexample.json | jq '.other|keys' | sort | uniq > other.json
Thanks in advance
The sample input is not JSON, which does not allow fancy quotes to be used as string delimiters. The following assumes the input has been corrected.
The value of .other is a JSON string; you can use fromjson to change the string to a JSON object.
sort|unique is redundant, as unique first sorts its input.
Putting it all together:
$ jq '.other | fromjson | keys_unsorted | unique' input.json
[
"client_timestamp",
"ios_page_index"
]
[
"client_timestamp",
"ios_index_path_row",
"ios_page_index"
]
(Using keys_unsorted saves one sort operation.)

Json JQ Filter with Wildcard in Bash

Json input:
[ "orange-1234", "orange-12345", "apple-1234" ]
Desired output:
[ "orange-1234, "orange-12345" ]
Via bash, I would like to use jq to find the values starting or containing orange*
I would like the output to contain the complete value. I have explored using jq startswith and contains, but only was able to return true or false
As of jq 1.5, you could do regular expression matching. So with that, just filter your array.
map(select(test("\\borange\\b")))
startswith and contains can do this just fine. Use select to filter values by true/false:
map(select(startswith("orange")))