how to add a key in yaml file using sed - shell

I have a scenario like this:
manifest.yaml
key1: "value1"
key2: "value2"
And I want to update this manifest.yaml file at run time to this
key1: "value1"
key2: "value2"
new_key: "new_value1"
so how can I add a new key at run time?

Achieved the same by the following command:
sed -i '/key2: "value2"/a new_key: "new_value1"' manifest.yml
and in case if space(5) has to be added before inserting new_key: "new_value1" then it can be done in the following way :
sed -i '/key2: "value2"/a \ \ \ \ \ new_key: "new_value1"' manifest.yml

Related

environment variable as key in yq4

I am using yq v4.27.2 and want to achieve this using the environment variable as the key:
yq -n '.key1.key2="value"'
key1:
key2: value
However, I get the error as:
export KEY=key1.key2; yq -n '.env(KEY)="value"'
Error: 1:6: invalid input text "KEY)=env(VALUE)"
With this, the whole key is treated as one node,
export KEY="key1.key2"; yq -n '.[env(KEY)]="value"'
key1.key2: value
What is the right syntax? Thanks
Found the syntax after reading the source code here https://github.com/mikefarah/yq/blob/master/pkg/yqlib/operator_env_test.go#L61
export KEY=.key1.key2; ./yq -n 'eval(strenv(KEY))="value"'
key1:
key2: value

How to read key=value variables from one file and replace ${key} in another file?

Similar to e.g. this: Parse out key=value pairs into variables
.env
key1=value1
key2=value2
config.yml
some:
key1: ${key1}
key2: ${key2}
How can I replace the values in config.yml with the values from .env?
So far I got this:
awk 'FNR==NR {n=index($1,"=");if(n){vars[substr($i, 1, n - 1)]=substr($i, n + 1)}; next } { for (i in vars) gsub("${"i"}", vars[i]) }1' .env file.yml
^- Can't figure out how to replace $
I can make it work with {key1} but not with ${key1}. How can I achieve this?
The simplest would be:
. .env
export key1 key2
envsubst '$key1 $key2' < config.yml
Can't figure out how to replace $
Seems you have to escape $ and { and }, like:
gsub("\\$\\{"i"\\}", vars[i])
Without using awk:
(set -a; source .env; envsubst < config.yml)
some:
key1: value1
key2: value2
(...): Runs command line in a sub-shell to avoid polluting current shell's environment
set -a: Exports all declaring variables
source .env: Source in .env file
envsubst < config.yml: Substitutes env variables in config.yml

How to output key values from json to a table using jq?

I have this json which I get from an API.
{
"result": {
"key1": "val1",
"key2": "val2",
"key3": "val3"
}
}
I have the following shell script which creates headers for table in a text file. I want to extract key values from the above result object and put in the same text file where keys should go under KEYS and values under VALUES in the table. I am new to jq and shell and struggling to achieve this.
echo "%table"
echo -e "KEYS\tVALUES" > outputfile.txt
KEYVALS=$(curl -uuser:password
"http://localhost:8080/customapi")
# here I want to split the key values using jq and write to the outputfile.txt
cat outputfile.txt
Outcome I am expecting is:
KEYS VALUES
key1 val1
key2 val2
key3 val3
How can I achieve this?
The key is to convert .result to an array of key/value pairs using to_entries, then outputing a set of strings (created using string interpolation) in raw mode.
% cat tmp.json
{
"result": {
"key1": "val1",
"key2": "val2",
"key3": "val3"
}
}
% jq -r '{"KEYS": "VALUES"} + .result | to_entries[] | "\(.key)\t\(.value)"' tmp.json
KEYS VALUES
key1 val1
key2 val2
key3 val3
I added the header to the input before conversion to the key/value list.
by adding the column call at the end the alignment will work for longer values as well ...
Note the usage of the # char as token separator ... of course if your data contains it this will not work ...
aws cognito-idp list-user-pools --max-results 20 | \
jq -r '.UserPools[]|to_entries[]|select (.key == "Name")|("\(.key):#\(.value)")'| column -t -s'#'
output
Name: corp_stg_user_pool
Name: corp_dev_user_pool

How can I add an indented line in the end of a yaml file with bash?

I have a file test.yaml with content:
'12345'
key1: 'foo'
key2: 'bar'
I have a system/env variable called ENV1 with value "baz"
How can I have this file as an outcome with bash?
'12345':
key1: 'foo'
key2: 'bar'
key3: 'baz'
$ sed "\$a\ key3: '$ENV1'" file
'12345'
key1: 'foo'
key2: 'bar'
key3: 'baz'
or set -i for in place.
Another alternative
$ cat file <(echo " key3: '$ENV1'")
I think this the easiest approach (this will write to the file):
echo " key3: '$ENV1'" >> file
If just want to print appending the content of the environment variable (not modifying the file)
cat file <(echo " key3: '$ENV1'")

Convert values from array in json object using bash shell

I am totaly new to shell..... let me ut the proper use case.
Use case:-
I have written two get method in my shell script, and when a user calls that script I will perform some operation for many id's using a for loop. like below
test_get1(){
value1=//performing some operation and storing it
value2=//performing some operation and storing it
//below line I am converting the o/p of value1 and value2 in json
value=$JQ_TOOL -n --arg key1 "$value1" --arg key2 "$value2" '{"key1":"\($value1)","key2":"\($value2)"}'
}
test_get2(){
arr=(1,2,3)
local arr_values=()
for value in arr
do
// Calling test_get1 for each iteraion of this loop, like below
val=$(test_get1 $value)
//below line will store the values in array
arr_values+=("$val")
done
}
When I am doing echo for the above arr_values, I am getting the below output
Output.
arr_values={
"key1":"value1",
"key2":"value2"
}
{
"key1":"value1",
"key2":"value2"
}
I want to convert the above value in json format like below.
json_value=[
{
"key1":"value1",
"key2":"value2"
},
{
"key1":"value1",
"key2":"value2"
}
]
I tried to do it with JQ, but unable to get the proper result.
Use the slurp option:
jq -s . in.json > out.json
in.json
{
"key1": "value1",
"key2": "value2"
}
{
"key1": "value1",
"key2": "value2"
}
out.json
[
{
"key1": "value1",
"key2": "value2"
}
]
[
{
"key1": "value1",
"key2": "value2"
}
]
1) Your existing "value=" line can be simplified to:
value=$(jq -n --arg key1 "$value1" --arg key2 "$value2" '\
{key1: $value1, key2: $value2}')
because --arg always interprets the provided value as a string, and because jq expressions need not follow all the rules of JSON.
2) From your script, arr_value is a bash array of JSON values. To convert it into a JSON array, you should be able to use an incantation such as:
for r in "${a[#]}" ; do printf "%s" "$r" ; done | jq -s .
3) There is almost surely a much better way to achieve your ultimate goal. Perhaps it would help if you thought about calling jq just once.

Resources