mjd
mjd

Reputation: 15

How to convert a json string into an individual character array in bash?

I have a json string that I need to convert into an array for passing a password in. Current issue is I need to do this for many users

Current json looks like this which was generated from

[
   {
        "password": "Password1",
        "loginId": "USER1"
   }
]

I need to change it to this

[ 
   { 
      "password":[ 
         "P",
         "a",
         "s",
         "s",
         "w",
         "o",
         "r",
         "d",
         "1"
      ],
      "loginId":"USER1"
   }
]

I'd prefer to do this in bash but if anyone has other options I'm open to anything.

Upvotes: 1

Views: 429

Answers (3)

Reino
Reino

Reputation: 3443

With Xidel you can use the XPath/XQuery function x:cps() twice to turn the string into an array and map:put() to update the JSON.

xidel -s input.json -e '[$json()/map:put(.,"password",x:cps(x:cps(password)))]'
[
  {
    "password": [
      "P",
      "a",
      "s",
      "s",
      "w",
      "o",
      "r",
      "d",
      "1"
    ],
    "loginId": "USER1"
  }
]

Online xidelcgi demo.

Upvotes: 1

Matias Barrios
Matias Barrios

Reputation: 5056

Handling JSON through Bash is a bad idea. Awk is not better at all but it can be done :

awk -F':' '
function ltrim(s) { sub(/^[ \t\r\n]+/, "", s); return s }
function rtrim(s) { sub(/[ \t\r\n]+$/, "", s); return s }
function trim(s) { return rtrim(ltrim(s)); }
!/"password"/ {
    print $0
}
/"password"/ {
    found=1;
    print $1 ":["
    password = $2
    gsub(/"|,/, " ", password)
    split(trim(password),letters,"")
    for(c=1; c <= length(letters); c++ ) {
        printf("\t\t\"%s\"",letters[c])
        if (c != length(letters)) {
            printf(",\n")
        }else{
            printf("\n\t\t]\n")
        }
    }
}
' input.txt

On the other hand. I think the right tool for this is Python 3 actually :

python3 -c '
import json

result = []

list = json.loads("""
[
   {
        "password": "Password1",
        "loginId": "USER1"
   }
]
""")
for item in list:
  result.append({ "loginId" : item["loginId"], "password" : [char for char in item["password"]] })

print(json.dumps(result, indent=4))
'

Hope this helps!

Upvotes: 0

oguz ismail
oguz ismail

Reputation: 50785

In jq, splitting a string by empty string results in a character array just as you need.

jq '.[].password |= split("")' file

Online demo at jqplay.org

Upvotes: 3

Related Questions