在bash中解析二维JSON数组

时间:2014-11-13 17:16:32

标签: json bash parsing

我目前感到很沮丧,因为我混淆了如何在bash中解析JSON。

我在bash脚本中对一个restful API做了一个基本的cURL请求,并获得了一个JSON数组作为响应,看起来像这样有多个条目:

[{"id":"012.mp4","language":"en","timestamp":1407517051,"name":"012.mp4"},{"id":"013.mp4","language":"en","timestamp":1407512051,"name":"013.mp4"}]

现在我必须在我的Bash脚本中解析这个JSON数组。我的目标是遍历所有条目,并且(w)获得用“name”指定的ressource。所以在上面这个例子中我想

wget 012.mp4

wget 013.mp4

我希望任何提示或片段如何存档。我甚至没有任何线索如何做到这一点,我读了一些关于使用python但我不知道python的事情。

4 个答案:

答案 0 :(得分:4)

jq工具为bash提供了一个易于使用的JSON解析器:

while read -r name; do
  wget "$name"
done < <(curl http://your.url/ | jq -r .[].name)

您可以直接测试:

jq -r .[].name <<<'[{"name": "hello"}, {"name": "world"}]'

返回:

hello
world

答案 1 :(得分:0)

如果你不想要完整的json解析,对于这样简单的文件,你也可以快速和肮脏地破解:

sed -En -e 's/}/\n/' -e 's/.*name":"(.*mp4)".*/\1/p' < file.json

此外,您可以尝试json_reformat命令,然后传递给sed以提取值。

答案 2 :(得分:0)

Pure BASH ---只是为了好玩:

#!/bin/bash

string='[{"id":"012.mp4","language":"en","timestamp":1407517051,"name":"012.mp4"},{"id":"013.mp4","language":"en","timestamp":1407512051,"name":"013.mp4"}]'

string2="${string//\},\{/ }"
oldifs="$IFS"; IFS=' '
array=( $string2 )
IFS="$oldifs"

for i in "${array[@]}"; do
after_last_colon="${i##*:}"
echo "wget ${after_last_colon//[\}\]]/}"
done <<< "$array"

结果:

wget "012.mp4"
wget "013.mp4"

答案 3 :(得分:0)

我使用jq创建了自己的python。使用python,我们可以将json的内容导入字典。然后,我们使用python语法访问字典的任何部分。

  • data-漂亮地打印JSON
  • len( data )-2
  • data[ 0 ][ 'name' ]-012.mp4
  • data[ 1 ][ 'name' ]-013.mp4

这是一个工作示例:

sample() {
  cat <<EOF
[{"id":"012.mp4","language":"en","timestamp":1407517051,"name":"012.mp4"},{"id":"013.mp4","language":"en","timestamp":1407512051,"name":"013.mp4"}]
EOF
}

jq_py() {
cat <<EOF
import json, sys
data = json.load( sys.stdin )
print( json.dumps( $1, indent = 4 ) )
EOF
}

jq() {
  python -c "$( jq_py "$1" )"
}

unquote_py() {
cat <<EOF
import json,sys
print( json.load( sys.stdin ) )
EOF
}

unquote() {
  python -c "$( unquote_py )"
}

sample | jq "data"
# [
#     {
#         "timestamp": 1407517051,
#         "id": "012.mp4",
#         "language": "en",
#         "name": "012.mp4"
#     },
#     {
#         "timestamp": 1407512051,
#         "id": "013.mp4",
#         "language": "en",
#         "name": "013.mp4"
#     }
# ]

sample | jq "len( data )"
# 2

sample | jq "data[ 0 ][ 'name' ]" | unquote
# 012.mp4

sample | jq "data[ 1 ][ 'name' ]" | unquote
# 013.mp4