Merge json files - Concatenate into a single dict json file - json

here are 3 JSON files
File1
{
"component1": [
]
}
File2
{
"component2": [
]
}
File3
{
"component3": [
]
}
Don't find the jq command line that would give this JSON file as jq output:
{
"components": {
"component1": [
],
"component2": [
],
"component3": [
]
}
}
Many thanks for your support
Best Regards.

Iterate over the input objects one a time from inputs and append it to the components using the reduce function
jq -n 'reduce inputs as $d (.; .components += $d )' file{1..3}.json

You can simply use add, e.g.
jq -s '{components: add}' file{1..3}.json
or:
jq -n '{components: [inputs]|add}' file{1..3}.json

Related

jq combine json files into single array

I have several json files I want to combine. Some are arrays of objects and some are single objects. I want to effectively concatenate all of this into a single array.
For example:
[
{ "name": "file1" }
]
{ "name": "file2" }
{ "name": "file3" }
And I want to end up with:
[
{ "name": "file1" }
{ "name": "file2" },
{ "name": "file3" },
]
How can I do this using jq or similar?
The following illustrates an efficient way to accomplish the required task:
jq -n 'reduce inputs as $in (null;
. + if $in|type == "array" then $in else [$in] end)
' $(find . -name '*.json') > combined.json
The -n command-line option is necessary to avoid skipping the first file.
This did it:
jq -n '[inputs] | add' $(find . -name '*.json') > combined.json

jq: add new elements to list from other file

I have two json files.
File 1:
{
"data": {
"items": []
}
}
File 2:
[
{
"name": "first name",
"path": [{
"matcher": "exact",
}]
},
{
...
}
]
I want to add all items from File 2 to the .data.items list in File 1.
How can I accomplish this?
Thanks in advance!
if you're willing to normalize the detail file:
items=$(jq -c ' . | { data: { items: . }} ' 2.json)
jq -s '{ data: { items: map(.data.items[])}}' 1.json <(echo $items)
Assuming both files contain valid JSON, you could do worse than:
jq --argfile extra 2.json '.data.items += $extra' 1.json

How to combine update with function result in jq?

Given data like this:
cat << EOF > xyz.json
[
{
"batch_id": 526,
"aCods": [
"IBDD879"
]
},
{
"batch_id": 357,
"aCods": [
"IBDD212"
]
}
]
EOF
What is the correct way to get this result?
[
{
"batch_id": "00000526",
"aCods": [
"IBDD879"
]
},
{
"batch_id": "00000357",
"aCods": [
"IBDD212"
]
}
]
I have tried three different commands hoping to be able to update a object element in an array with the result of a function on that element.
I just cannot find the right syntax.
jq -r '.[] | .batch_id |= 9999999' xyz.json;
{
"batch_id": 9999999,
"aCods": [
"IBDD879"
]
}
{
"batch_id": 9999999,
"aCods": [
"IBDD212"
]
}
jq -r '.[] | lpad("\(.batch_id)";8;"0")' xyz.json;
00000526
00000357
jq -r '.[] | .batch_id |= lpad("\(.batch_id)";8;"0")' xyz.json;
jq: error (at /dev/shm/xyz.json:14): Cannot index number with string "batch_id"
Assuming you are trying to use the lpad/2 from this peak’s comment, you can do
def lpad($len; $fill): tostring | ($len - length) as $l | ($fill * $l)[:$l] + .;
map(.batch_id |= lpad(8; "0"))
The key here is when using the update assignment operator |= the field being modified is passed on internally, so that you don’t have to call it out explicitly in the RHS

jq: convert array to object indexed by filename?

Using jq how can I convert an array into object indexed by filename, or read multiple files into one object indexed by their filename?
e.g.
jq -s 'map(select(.roles[]? | contains ("mysql")))' -C dir/file1.json dir/file2.json
This gives me the data I want, but I need to know which file they came from.
So instead of
[
{ "roles": ["mysql"] },
{ "roles": ["mysql", "php"] }
]
for output, I want:
{
"file1": { "roles": ["mysql"] },
"file2": { "roles": ["mysql", "php"] }
}
I do want the ".json" file extension stripped too if possible, and just the basename (dir excluded).
Example
file1.json
{ "roles": ["mysql"] }
file2.json
{ "roles": ["mysql", "php"] }
file3.json
{ }
My real files obviously have other stuff in them too, but that should be enough for this example. file3 is simply to demonstrate "roles" is sometimes missing.
In other words: I'm trying to find files that contain "mysql" in their list of "roles". I need the filename and contents combined into one JSON object.
To simplify the problem further:
jq 'input_filename' f1 f2
Gives me all the filenames like I want, but I don't know how to combine them into one object or array.
Whereas,
jq -s 'map(input_filename)' f1 f2
Gives me the same filename repeated once for each file. e.g. [ "f1", "f1" ] instead of [ "f1", "f2" ]
If your jq has inputs (as does jq 1.5) then the task can be accomplished with just one invocation of jq.
Also, it might be more efficient to use any than iterating over all the elements of .roles.
The trick is to invoke jq with the -n option, e.g.
jq -n '
[inputs
| select(.roles and any(.roles[]; contains("mysql")))
| {(input_filename | gsub(".*/|\\.json$";"")): .}]
| add' file*.json
jq approach:
jq 'if (.roles[] | contains("mysql")) then {(input_filename | gsub(".*/|\\.json$";"")): .}
else empty end' ./file1.json ./file2.json | jq -s 'add'
The expected output:
{
"file1": {
"roles": [
"mysql"
]
},
"file2": {
"roles": [
"mysql",
"php"
]
}
}

How to loop through a json key that value is an array

I am somewhat new to bash. My Objective is to loop through the JSON and capture the user input and export it to environment variable.
This is the structure of the json. Any help will be appreciated!
{
"items": [{
"Gitlab": [
"GITLAB_URL",
"GITLAB_TOKEN",
"GITLAB_CHANNEL",
"GITLAB_SHOW_COMMITS_LIST",
"GITLAB_SHOW_MERGE_DESCRIPTION",
"GITLAB_DEBUG",
"GITLAB_BRANCHES"
]
},
{
"PagerDuty": [
"PAGERV2_API_KEY",
"PAGERV2_SCHEDULE_ID",
"PAGERV2_SERVICES",
"PAGERV2_DEFAULT_RESOLVER",
"PAGERV2_ENDPOINT",
"PAGERV2_ANNOUNCE_ROOM",
"PAGERV2_NEED_GROUP_AUTH",
"PAGERV2_LOG_PATH"
]
},
{
"SLack": [
"SLACK_TOKEN"
]
}
]
}
This is what I have so far
jq '.items[] | select( .Gitlab| startswith("first-block-"))' < configurations.json
for i in ${items[#]}
do
echo "Enter your " $i
read input
if [[ ! -z "$input" ]]; then
export $i=$input
fi
done