0

I'm generating a JSON file with a shell script but I can't find a solution to automatically get rid of the last comma just before the ending "}".

Here is my code:

echo "{" >> out_file
for i in 3 4 5 6 7 #ends at 298
do
y=$i
sommeMag=`awk -F '=' '/'$y'/{sommeMag+=$2}END{print sommeMag}'` "/myfolder/... "
store="mag$y"
if [ -z "$sommeMag" ] #checks is variable is empty
    then
        echo  "\"" $store"\"":0",">> out_file
    else
        echo "\""$store"\"":$sommeMag"," >> out_file
    fi
done
echo "}" >> out_file

The file is ending this way :

{
" mag297":0,
" mag298":0, <-- syntaxt error
}

The file should end this way :

{
...
" mag297":0,
" mag298":0 <-- no more comma
}

How can I manage that?

The code has been edited to be more readable here.

  • show how should look the whole result – RomanPerekhrest May 26 '17 at 9:21
  • @RomanPerekhrest edited my post – Matieu May 26 '17 at 9:29
  • 1
    1) use echo -n to omit new line when printing variable. 2) have a comma var initialize after first loop and printed before each var. – Archemar May 26 '17 at 9:52
  • Do you really have to use shell scripts ? I mean, other tools like python or perl could deal with it much better – Sergiy Kolodyazhnyy May 26 '17 at 11:07
1

What you should be doing is printing first item, and let the cursor stop. Then you can start working on the loop and advance the cursor by inserting comma and newline. printf is more helpful than echo in that regard. To prevent excessive repetition and shorten the code, use functions.

Since I don't have the files you're parsing with awk, i can't work with your script but the example below illustrates what I'm trying to convey.

#!/bin/bash

print_entry(){
    # sommeMag would be variable $2, $1 is store
    if [ -z $2 ]
    then
        printf '"%s":0' "$1" 
    else
        printf '"%s":%s' "$1" "$2"
    fi
}

# main part of the script
printf "%s\n" "{"

# do the first one unconditionally but without comma
print_entry "something1" "something2"
for i in 2 3 4 5
do
    # because first one was printed unconditionally
    # now we just keep printing comma and moving cursor
    # to newline to insert the new entry
    printf ",\n"
    print_entry "something$i" "$i"
done
printf "\n%s"  "}"

Sample run

$ ./make_json.sh                                                                                                                                      
{
"something1":something2,
"something2":2,
"something3":3,
"something4":4,
"something5":5
}$ 

The above approach is typically what I call "add comma behind". Another approach would be "Add comma ahead", but instead of for loop, use while loop with counter to simulate C-style for loop behavior. If you reach last item, don't output comma. Basically

counter=1
while [ $counter -le 298 ]
do
    $json_value=$(command1)
    if [ $counter -ne 298  ]
    then
        echo $json_value ,
    else
        echo $json_value
    fi 
    $counter=$(($counter+1))
done
1
#
# var initialzizations
#
# newline
NL=`printf '\nn'`;NL=${NL%?}

# double quote
q=\"

# separator set to a comma+newline
sep=",$NL"

# container for the json result
json=;

# begin/end of count values
start=3
 stop=7

# looping
# in case seq utility not found, then you can use: yes | sed -ne "$start,$stop=;${stop}q"
for i in `seq "$start" "$stop"`
do
   y=$i
   sommeMag=`awk -F = "/$y/"'{sommeMag+=$2}END{print sommeMag}'` "/myfolder/... "
   store=mag$y
   json=${json:-}${json:+"$sep"}$q\ $store$q:${sommeMag:-0}
done

# remove the separtor from the end and also place a newline
json=${json%"$sep"}$NL

printf '{\n%s}\n' "$json" >> out_file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.