Shell
在 shell 腳本中循環遍歷 JSON 數組
下面是 curl 命令輸出(關於分支的文件資訊),需要腳本或命令來列印文件名、文件類型和大小。
我嘗試過
jq
但能夠獲取單個值(jq '.values[].size'
){ "path": { "components": [], "name": "", "toString": "" }, "revision": "master", "children": { "size": 5, "limit": 500, "isLastPage": true, "values": [ { "path": { "components": [ ".gitignore" ], "parent": "", "name": ".gitignore", "extension": "gitignore", "toString": ".gitignore" }, "contentId": "c9e472ef4e603480cdd85012b01bd5f4eddc86c6", "type": "FILE", "size": 224 }, { "path": { "components": [ "Jenkinsfile" ], "parent": "", "name": "Jenkinsfile", "toString": "Jenkinsfile" }, "contentId": "e878a88eed6b19b2eb0852c39bfd290151b865a4", "type": "FILE", "size": 1396 }, { "path": { "components": [ "README.md" ], "parent": "", "name": "README.md", "extension": "md", "toString": "README.md" }, "contentId": "05782ad495bfe11e00a77c30ea3ce17c7fa39606", "type": "FILE", "size": 237 }, { "path": { "components": [ "pom.xml" ], "parent": "", "name": "pom.xml", "extension": "xml", "toString": "pom.xml" }, "contentId": "9cd4887f8fc8c2ecc69ca08508b0f5d7b019dafd", "type": "FILE", "size": 2548 }, { "path": { "components": [ "src" ], "parent": "", "name": "src", "toString": "src" }, "node": "395c71003030308d1e4148b7786e9f331c269bdf", "type": "DIRECTORY" } ], "start": 0 } }
預期輸出應如下所示
.gitignore FILE 224 Jenkinsfile FILE 1396
對於問題中提供的案例,@JigglyNaga 的答案可能比這更好,但對於一些更複雜的任務,您還可以使用以下方式遍歷列表項
keys
:來自
file
:for k in $(jq '.children.values | keys | .[]' file); do ... done
或從字元串:
for k in $(jq '.children.values | keys | .[]' <<< "$MYJSONSTRING"); do ... done
因此,例如,您可以使用:
for k in $(jq '.children.values | keys | .[]' file); do value=$(jq -r ".children.values[$k]" file); name=$(jq -r '.path.name' <<< "$value"); type=$(jq -r '.type' <<< "$value"); size=$(jq -r '.size' <<< "$value"); printf '%s\t%s\t%s\n' "$name" "$type" "$size"; done | column -t -s$'\t'
如果值沒有換行符,則可以
jq
在循環內通過一次呼叫來實現它,這會使其更快:for k in $(jq '.children.values | keys | .[]' file); do IFS=$'\n' read -r -d '' name type size \ <<< "$(jq -r ".children.values[$k] | .path.name,.type,.size" file)" printf '%s\t%s\t%s\n' "$name" "$type" "$size"; done | column -t -s$'\t'