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

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 665

Latest Images

Trending Articles



Latest Images