JSON list (not object) to Bash array?

后端 未结 1 1940
猫巷女王i
猫巷女王i 2021-01-28 08:56

I\'ve got a JSON list (the value of a key-value pair containing a list of items):

[ \"john\", \"boris\", \"joe\", \"frank\" ]

How would I convert th

相关标签:
1条回答
  • 2021-01-28 09:37

    Easy Case: Newline-Free Strings

    The simple approach is to use jq to transform your list into a line-per-item, and read that into your script:

    json='[ "john", "boris", "joe", "frank" ]'
    readarray -t your_array < <(jq -r '.[]' <<<"$json")
    declare -p your_array
    

    ...properly emits:

    declare -a your_array=([0]="john" [1]="boris" [2]="joe" [3]="frank")
    

    Tricky Case: Strings With Newlines

    Sometimes you need to read strings that can contain newlines (or want to avoid security risks caused by malicious or malformed data being read into the wrong fields). To avoid that, you can use NUL delimiters between your data (and remove any NUL values contained therein):

    json='[ "john\ndoe", "marco\nquent", "malicious\u0000data" ]'
    
    array=( )
    while IFS= read -r -d '' item; do
      array+=( "$item" )
    done < <(jq -j '.[] | ((. | sub("\u0000"; "<NUL>")) + "\u0000")' <<<"$json")
    
    declare -p array
    

    ...properly emits:

    declare -a array=([0]=$'john\ndoe' [1]=$'marco\nquent' [2]="malicious<NUL>data")
    

    ...and printf '<%s>\n\n' "${array[@]}" properly emits:

    <john
    doe>
    
    <marco
    quent>
    
    <malicious<NUL>data>
    

    (Note that very new bash has readarray -0, which can avoid the need for the while IFS= read -r -d '' loop given above, but that's not common yet. Also note that you can use that loop to directly iterate over content from jq, avoiding the need to store content in an array in the first place; see BashFAQ #1).

    0 讨论(0)
提交回复
热议问题