I’m writing a bash script to read a JSON file and export the key-value pairs as environment variables. Though I could extract the key-value pairs, I’m struggling to skip those entries that failed to parse by jq
.
JSON (key3 should fail to parse)
{
"KEY1":"ABC",
"KEY2":"XYZ",
"KEY3":"---ABC---n
dskfjlksfj"
}
Here is what I tried
for pair in $(cat test.json | jq -r -R '. as $line | try fromjson catch $line | to_entries | map("(.key)=(.value)") | .[]' ); do
echo $pair
export $pair
done
And this is the error
jq: error (at <stdin>:1): string ("{") has no keys
jq: error (at <stdin>:2): string (" "key1...) has no keys
My code is based on these posts:
4
Answers
[Note: this response was made to the original question, which has since been changed. The response essentially assumes the input consists of JSONLines interspersed with other lines.)
Since the goal seems to be to ignore lines that don’t have valid key-value pairs, you can simply use
catch empty
:Note also the use of
@sh
and of the shell’sread
, and the fact that.value
(in jq) and$line
(in the shell) are both quoted. These are all important for robustness, though further refinements might still be necessary for additional robustness.Here’s a response to the revised question. Unfortunately, it will only be useful in certain limited cases, not including the example you give. (Basically, it depends on jq’s parser being able to recover before the end of file.)
Note that further refinements may be warranted, especially if there is potentially something fishy about the key names being used as shell variable names.
Perhaps there is an algorithm that will repair the broken JSON produced by the upstream system. If not, the following is a horrible but possibly useful "hack" that will at least capture KEY1 and KEY2 in the example in the Q:
The broken JSON in the example could be repaired in a number of ways, e.g.:
produces:
At least that’s JSON 🙂