我有一個 json 檔案,其中包含我想添加到 bash 陣列中的鍵和值,但我無法使其作業。
1. 使用資料創建 JSON 檔案
# JSON file
echo '{"persons": [{"name":"John", "age":30, "car":"big"}, {"name":"Alice", "age":29, "car":"big"}]}' > my.json
2. 迭代姓名和年齡
# Looping over JSON
jq -c '.persons[]' my.json | while read p;
do
name=$(echo $p | jq -r '.name')
age=$(echo $p | jq -r '.age')
echo "Name: $name"
echo "Age: $age"
done
姓名和年齡按預期列印出來。
3.手動添加姓名和年齡到陣列
# Creating array and adding elements
declare -A mylookup
key="James"
value="31"
mylookup[$key]=$value
4. 檢查是否添加了值
for key in "${!mylookup[@]}"
do
echo "Key: $key"
echo "Value: ${lookup[$value]}"
done
我奇怪地只正確顯示了鑰匙
5. 回圈添加姓名和年齡到陣列
# Creating array and adding elements
declare -A mylookup
jq -c '.persons[]' my.json | while read p;
do
name=$(echo $p | jq -r '.name')
age=$(echo $p | jq -r '.age')
mylookup[$name]=$age
done
6. 列印出 Array 中的鍵和值
現在我檢查添加到陣列中的內容。
for key in "${!mylookup[@]}"
do
echo "Key: $key"
echo "Value: ${lookup[$value]}"
done
什么都沒有列印出來......我在哪里失敗了?我懷疑在向陣列中添加鍵和值時出了點問題,但我不知道是什么。
uj5u.com熱心網友回復:
陣列值正在丟失,因為您在這里使用了管道。由于 while 回圈在分叉的子 shell 中運行,因此所有變數都僅在分叉的子 shell 中設定,并且您在父 shell 中沒有看到任何變化。
您可以使用它來避免這種情況:
declare -A mylookup
while IFS=$'\t' read n a; do
mylookup[$n]="$a"
done < <(jq -r '.persons[] | "\(.name)\t\(.age)"' my.json)
# check array content
declare -p mylookup
declare -A mylookup=([Alice]="29" [John]="30" )
< <(...)是程序替代
uj5u.com熱心網友回復:
通常的方法是使jq輸出成為 shell 可以準確讀取的格式。以下是無損 TSV 格式的示例:
#!/bin/bash
declare -A mylookup
while IFS=$'\t' read -r name age
do
printf -v name '%b' "$name"
printf -v age '%b' "$age"
mylookup["$name"]=$age
done < <(
echo '{"persons": [{"name":"John", "age":30, "car":"big"}, {"name":"Alice", "age":29, "car":"big"}]}' |
jq -r '.persons[] | [ .name, .age ] | @tsv'
)
declare -p mylookup
#=> mylookup='([Alice]="29" [John]="30" )'
備注:旨在printf -v ... '%b' ...對 TSV 值進行轉義;在您的情況下,它們可能是不必要的
uj5u.com熱心網友回復:
或者,您可以使用jq為 Bash 的declare -A陳述句輸出有效的 bash 語法。
通過適當的@sh過濾jq,它可以確保 JSON 資料不會發生無效或意外執行。
這種方法節省了使用效率非常低的 shell 迭代。
#!/usr/bin/env bash
json_file=my.json
if dyn_declare=$(
jq --raw-output '"(",(.persons[]|"[" (.name|@sh) "]=" (.age|@sh)),")"' \
"$json_file"
) && declare -A mylookup=$dyn_declare; then
# Do something useful with the populated associative array
# Here we just dump it for debug/demo purpose
declare -p mylookup
else
printf 'Could not parse %s into an associative array\n' \
"$json_file" >&2
exit 1
fi
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/477187.html
上一篇:PostgreSQL13.6-查詢JSON導致“操作員不存在:json->記錄”
下一篇:C#從檔案中獲取Json值
