Thursday, October 27, 2022

[SOLVED] Weird array output in shell script

Issue

The content extracted from the file is separated and stored in an array, and print the content using loop. Only printing the last element is weird. I'll show you my code. How can I resolve this problem?

[config.json]

{ 
  "id": "hello",
  "passwd": "1234",
  "languageList": ["ko", "en"]
}

[test.sh]

# BEFORE_CONFIG and AFTER_CONFIG have same code
BEFORE_CONFIG=~/workspace/env/config.json
AFTER_CONFIG=~/workspace/config/config.json

BEF_LANG=$(grep "\[" ${BEFORE_CONFIG} | tr -d '\[' | tr -d '\]' | tr -d '"' | tr -d ' ' | cut -d ":" -f2)
AF_LANG=$(grep "\[" ${AFTER_CONFIG} | tr -d '\[' | tr -d '\]' | tr -d '"' | tr -d ' ' | cut -d ":" -f2)

echo "before lang :: ${BEF_LANG}"
echo "after lang :: ${AF_LANG}"


IFS=',' read -r -a AF_LANG_LIST <<< "$AF_LANG"

echo "after lang list print >> ${AF_LANG_LIST[@]}"
echo "list length >> ${#AF_LANG_LIST[@]}"


for element in ${AF_LANG_LIST[@]}
do
            echo "${element}"
            echo "This language !!! ${element} !!! print !!!!"
done

[result]

$ source tesh.sh

before lang :: ko,en
after lang :: ko,en
after lang list >> ko en
list length >> 2
ko
This language !!! ko !!! print !!!!
en
 !!! print !!!!!! en   # expect result → This language !!! en !!! print !!!!

Solution

You can use jq to parse the json correctly, and extract languageList do:

cat ~/workspace/env/config.json|jq .languageList[] -r|xargs

which will output:

ko en

which you can later use in your script

Trying to parse JSON with tr & cut is prone to so many errors.

Here is the example for your script:

#!/bin/bash
# BEFORE_CONFIG and AFTER_CONFIG have same code
BEFORE_CONFIG=~/workspace/env/config.json
AFTER_CONFIG=~/workspace/config/config.json

BEF_LANG=$(grep "\[" ${BEFORE_CONFIG} | tr -d '\[' | tr -d '\]' | tr -d '"' | tr -d ' ' | cut -d ":" -f2)
#AF_LANG=$(grep "\[" ${AFTER_CONFIG} | tr -d '\[' | tr -d '\]' | tr -d '"' | tr -d ' ' | cut -d ":" -f2)

AF_LANG=$(cat ${BEFORE_CONFIG}|jq .languageList[] -r|xargs)

echo "before lang :: ${BEF_LANG}"
echo "after lang :: ${AF_LANG}"

# you do not need this
#IFS=',' read -r -a AF_LANG_LIST <<< "$AF_LANG"

#echo "after lang list print >> ${AF_LANG_LIST[@]}"
#echo "list length >> ${#AF_LANG_LIST[@]}"


for element in ${AF_LANG[@]}
do
            echo "${element}"
            echo "This language !!! ${element} !!! print !!!!"
done


Answered By - Ron
Answer Checked By - Mary Flores (WPSolving Volunteer)