在shell脚本中解析json数组

时间:2016-08-30 12:12:47

标签: json bash shell unix grep

我需要从json字符串中打印键和值。我已经解析了一个简单的json字符串

name=""

我的代码就像这样

            {
              "Name": "test1",
              "CreateDate": "2016-08-30T10:52:52Z",
              "Id": "testId1",
            }

但是这段代码不适用于像这样的json字符串

 q1=$(echo $x | grep -Po '"Name":.*?[^\\]",'| perl -pe 's/"Name": //; s/^"//; s/",$//');

 q2=$(echo $x | grep -Po '"Id":.*?[^\\]",'| perl -pe 's/"Id": //; s/^"//; s/",$//');

    echo $q1 "," $q2;

我需要像这样打印

x='{    "TestNames":
        [{
        "Name": "test1",
        "CreateDate": "2016-08-30T10:52:52Z",
        "Id": "testId1"
         }, 
         {
        "Name":  "test2",
        "CreateDate": "2016-08-30T10:52:13Z",
        "Id": "testId2"
    }]
}';

是否可以使用grep命令获取这样的数据?

2 个答案:

答案 0 :(得分:8)

首先,你的数据无效json,有一个逗号太多了:

{
  "TestNames": [
    {
      "Name": "test1",
      "CreateDate": "2016-08-30T10:52:52Z",
      "Id": "testId1", <--- Remove that!
    },
    {
      "Name": "test2",
      "CreateDate": "2016-08-30T10:52:13Z",
      "Id": "testId2"
    }
  ]
}

一旦你修复了你可以使用jq在命令行上解析json:

echo "$x" | jq -r '.TestNames[]|"\(.Name) , \(.Id)"'

如果您需要保留输出值。

declare -A map1

while read name id ; do
    echo "$name"
    echo "$id"
    map1[$name]=$id

done < <(echo "$x" | jq -r '.TestNames[]|"\(.Name) \(.Id)"')

echo "count : ${#map1[@]}"
echo "in loop: ${map1[$name]}"

答案 1 :(得分:2)

我建议使用jq,一个命令行JSON解析器:

$ echo '''{
          "Name": "test1",
          "CreateDate": "2016-08-30T10:52:52Z",
          "Id": "testId1"
        }''' | jq  '.Name + " , " + .Id'

"test1 , testId1"


$ echo '''{    "TestNames":
    [{
    "Name": "test1",
    "CreateDate": "2016-08-30T10:52:52Z",
    "Id": "testId1"
     },
     {
    "Name":  "test2",
    "CreateDate": "2016-08-30T10:52:13Z",
    "Id": "testId2"
}]
}''' | jq '.TestNames[] | .Name + " , " + .Id'

"test1 , testId1"
"test2 , testId2"