I am using shell script to update JSON. Previously I used jq command to read/write an JSON object. However it seems not every bash environment support jq command. I tried to resolve this issue by manipulating the string using awk, sed and gsup.
However the syntax is so complicated as below:
update_json_key() { local key="$1" local value="$2" local filename="$3" if [[ ! -f "$filename" ]]; then echo "{}" > "$filename" fi SED_INPLACE="" if [[ "$OSTYPE" == "darwin"* ]]; then SED_INPLACE="-i ''" # macOS requires an empty extension for in-place editing else SED_INPLACE="-i" # Linux fi # Ensure the file exists and is a valid JSON object if [ ! -s "$filename" ] || ! grep -q "{" "$filename"; then echo "{}" > "$filename" fi # Check if the key exists if grep -q "\"$key\": " "$filename"; then # Key exists, update it # This regex ensures we don't capture more than we need by being specific with our patterns sed $SED_INPLACE "s/\"$key\": \"[^\"]*\"/\"$key\": \"$value\"/" "$filename" else # Key does not exist, add it if grep -q "^{}$" "$filename"; then # File has only empty JSON, directly add key without comma sed $SED_INPLACE "s/{}/{\"$key\": \"$value\"}/" "$filename" else # File is non-empty, append key before the last closing brace # This ensures that we correctly find the last closing brace even when it's not at the very end sed $SED_INPLACE "s/\(.*\)}$/\1, \"$key\": \"$value\"}/" "$filename" fi fi if [ -e "$filename''" ]; then rm -f "$filename''" fi if [[ -e "$filename" ]] && [[ $(wc -l < "$filename") -gt 1 ]]; then raw_json=$(sed -e ':a' -e 'N' -e '$!ba' -e 's/\n//g' -e 's/": \?"/": "/g' -e 's/, \?"/,"/g'"$filename") rm -f $filename echo "$raw_json" > "$filename" fi formatted_json=$(awk 'BEGIN { FS=","; print "{" } { gsub(/[{}]/, ""); n = split($0, a, ","); for (i = 1; i <= n; i++) { gsub(/^[[:space:]]+|[[:space:]]+$/, "", a[i]); print " " a[i] (i < n ? "," : ""); } } END { print "}" }'"$filename") rm -f $filename echo "$formatted_json" > "$filename"}And this syntax not yet handled any nested JSON object iteration yet. I m thinking if there is an easier way to manipulate JSON object with shell script without using jq.