Quantcast
Channel: Active questions tagged jq - Stack Overflow
Viewing all articles
Browse latest Browse all 657

How to update JSON file in shell script without using jq?

$
0
0

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.


Viewing all articles
Browse latest Browse all 657

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>