Bash
將 JSON 數組轉換為 Bash
我正在使用
JQ
從測驗數據庫中獲取一些 JSON,並且我想解析結果。我正在嘗試將結果數組保存在 Bash 中,如下所示,但格式是 JavaScript/Python 中使用的帶有方括號而不是 Bash 樣式的格式。quiz=$(curl -s https://opentdb.com/api.php?amount=3) answers=$(echo $quiz | jq '[ .results][0][0].incorrect_answers') correct=$(echo $quiz | jq '[ .results][0][0].correct_answer') answers+=( $correct )
答案的範例如下:
[ "Excitement", "Aggression", "Exhaustion" ]
由於格式錯誤,永遠不會將正確答案推送到數組中。
如何轉換上述格式的數組,以便在我的腳本中將其解釋為數組。
輸出範例
curl
(這不是硬編碼,問題和答案每次都不同):{ "response_code": 0, "results": [ { "category": "Entertainment: Television", "type": "multiple", "difficulty": "easy", "question": "Which company has exclusive rights to air episodes of the "The Grand Tour"?", "correct_answer": "Amazon", "incorrect_answers": [ "Netflix", "BBC", "CCTV" ] }, { "category": "Celebrities", "type": "multiple", "difficulty": "medium", "question": "How much weight did Chris Pratt lose for his role as Star-Lord in "Guardians of the Galaxy"?", "correct_answer": "60 lbs", "incorrect_answers": [ "30 lbs", "50 lbs", "70 lbs" ] }, { "category": "Animals", "type": "boolean", "difficulty": "easy", "question": "The Killer Whale is considered a type of dolphin.", "correct_answer": "True", "incorrect_answers": [ "False" ] } ] }
我會
jq
逐行輸出結果。然後使用 bashmapfile
命令將行讀入數組mapfile -t correct < <(jq -r '.results[] | .correct_answer' <<<"$quiz") declare -p correct
declare -a correct=([0]="Amazon" [1]="60 lbs" [2]="True")
對於不正確的答案,由於 bash 沒有多維數組,我可以
jq
將不正確答案的數組輸出為 CSV:mapfile -t incorrect < <(jq -r '.results[] | .incorrect_answers | @csv' <<<"$quiz") declare -p incorrect
declare -a incorrect=([0]="\"Netflix\",\"BBC\",\"CCTV\"" [1]="\"30 lbs\",\"50 lbs\",\"70 lbs\"" [2]="\"False\"")
然後:
$ echo "q $i: ans=${correct[i]}; wrong=${incorrect[i]}" q 1: ans=60 lbs; wrong="30 lbs","50 lbs","70 lbs"
文件:
假設您正在與使用者互動:
i=0 read -p "Answer to question $i: " answer if [[ $answer == "${correct[i]}" ]]; then echo Correct elif [[ ${incorrect[i]} == *"\"$answer\""* ]]; then echo Incorrect else echo Invalid answer fi
請記住,內部運算符
[[...]]
不是字元串相等運算符,它是模式匹配運算符。==
- 第一個測試是簡單的字元串比較
- 第二個測試查看包含不正確答案的 CVS 字元串是否包含**雙引號中的答案
擴展@ RomanPerekhrest的答案(現在就去投票吧):
mapfile -t answers < <(jq -r '.results[] | [.correct_answer] + .incorrect_answers | @sh' <<<"$quiz") declare -p answers
declare -a answers=([0]="'Amazon' 'Netflix' 'BBC' 'CCTV'" [1]="'60 lbs' '30 lbs' '50 lbs' '70 lbs'" [2]="'True' 'False'")
然後,你可以使用這樣的東西
for i in "${!answers[@]}"; do declare -a "this_answers=( ${answers[i]} )" echo $i printf " > %s\n" "${this_answers[@]}" done
0 > Amazon > Netflix > BBC > CCTV 1 > 60 lbs > 30 lbs > 50 lbs > 70 lbs 2 > True > False