To get the key's value, you would use a JSON-aware tool, like jq rather than grep. You would do this for a few reasons:
- The value that you are extracting may be encoded. The
jq tool would decode this for you if you use it with the -r (--raw-output) option.
- Using
grep makes no distinction between values and keys, so you may accidentally extract data that you did not plan to extract.
Extracting the value of the CTE_LG_LL_OE key in the top-level en entry:
jq -r '.en.CTE_LG_LL_OE' file
Setting the value to the string ready and writing the resulting document to the file new-file:
jq '.en.CTE_LG_LL_OE |= "ready"' file >new-file
The |= operator is the "update operator" and it takes a "path" to a key to the left and a new value for the key on the right.
To set the value from a shell variable:
jq --arg newval "$newvalue" '.en.CTE_LG_LL_OE |= $newval' file >new-file
This creates a jq variable called $newval from the shell variable newvalue, which we then use in the jq expression. The value in the variable will automatically be JSON-encoded by jq.
For readability, space things out a bit (assuming this is part of a shell script, since the question is tagged with shell-script):
jq --arg newval "$newvalue" \
'.en.CTE_LG_LL_OE |= $newval' file >new-file
To do in-place editing of the file (jq does not support in-place editing by itself):
tmpfile=$(mktemp)
cp file "$tmpfile" &&
jq --arg newval "$newvalue" \
'.en.CTE_LG_LL_OE |= $newval' "$tmpfile" >file &&
rm -f "$tmpfile"
As a once-liner:
tmpfile=$(mktemp); cp file "$tmpfile" && jq --arg newval "$newvalue" '.en.CTE_LG_LL_OE |= $newval' "$tmpfile" >file && rm -f "$tmpfile"
If you're not sure of where in the document structure the CTE_LG_LL_OE key is located and just want to update the values of all CTE_LG_LL_OE keys that have the value warn:
jq '
(
.. |
select(type == "object" and .CTE_LG_LL_OE? == "warn").CTE_LG_LL_OE
) |= "ready"' file
This examines all keys and values recursively in the whole document. It finds all objects that has a CTE_LG_LL_OE key with th evalue warn and updates these to instead be ready. The newlines are only for readability.
The value could be taken from a shell variable as before:
jq --arg newval "$somevariable" '
(
.. |
select(type == "object" and .CTE_LG_LL_OE? == "warn").CTE_LG_LL_OE
) |= $newval' file
This could obviously be combined with doing in-place editing too, as show in the first half of this answer.