无法让jq识别json文件中的数组 [英] Can't get jq to recognize an array within a json file

查看:123
本文介绍了无法让jq识别json文件中的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要解析的json文件,格式如下:

I have a json file that I use for work that I need to parse that is in the following format:

(^)#(^)#(^)#(^)bminter@ubuntu:~$ cat jqtest
{
   "files":[
      {
         "BLOCK1":{
            "SUBBLOCK1":{
               "akey1":"avalue1",
               "bkey1":"bvalue1",
               "ckey1":"cvalue1"
            },
            "dkey1":"dvalue1",
            "key":"evalue1"
         }
      },
      {
         "BLOCK-2":{
            "SUBBLOCK2":{
               "akey2":"avalue2",
               "bkey2":"bvalue2"
            },
            "ckey2":"cvalue2",
            "key":"dvalue2"
         }
      },
      {
         "BLOCK-A":{
            "SUBBLOCK2":{
               "akey2":"avalue2",
               "bkey2":"bvalue2"
            },
            "ckey2":"cvalue2",
            "key":"dvalue2"
         }
      }],
   "NOBLOCK":"value",
   "key":"NOBLOCKvalue"
}

所以它是嵌套在json文件中的数组. jq .[] jqtest给了我文件中的所有内容.甚至数组之外的数据.除了数组之外,我只得到值而不是键:

So it's an array nested within a json file. jq .[] jqtest gives me everything in the file. Even the data outside the array. Except, outside the array, I'm only given the values not the keys:

(^)#(^)#(^)#(^)bminter@ubuntu:~$ jq .[] jqtest
[
  {
    "BLOCK1": {
      "SUBBLOCK1": {
        "akey1": "avalue1",
        "bkey1": "bvalue1",
        "ckey1": "cvalue1"
      },
      "dkey1": "dvalue1",
      "key": "evalue1"
    }
  },
  {
    "BLOCK-2": {
      "SUBBLOCK2": {
        "akey2": "avalue2",
        "bkey2": "bvalue2"
      },
      "ckey2": "cvalue2",
      "key": "dvalue2"
    }
  },
  {
    "BLOCK-A": {
      "SUBBLOCK2": {
        "akey2": "avalue2",
        "bkey2": "bvalue2"
      },
      "ckey2": "cvalue2",
      "key": "dvalue2"
    }
  }
]
"value"
"NOBLOCKvalue"
(^)#(^)#(^)#(^)bminter@ubuntu:~$ 

除此之外,我无法访问数组内的任何块:

Beyond that I can't access any block inside the array:

(^)#(^)#(^)#(^)bminter@ubuntu:~$ jq '.[].BLOCK1' jqtest
jq: error (at jqtest:36): Cannot index array with string "BLOCK1"
(^)#(^)#(^)#(^)bminter@ubuntu:~$ jq '.[].BLOCK-2' jqtest
jq: error (at jqtest:36): Cannot index array with string "BLOCK"
(^)#(^)#(^)#(^)bminter@ubuntu:~$ jq '.[].BLOCK-A' jqtest
jq: error: A/0 is not defined at <top-level>, line 1:
.[].BLOCK-A          
jq: 1 compile error
(^)#(^)#(^)#(^)bminter@ubuntu:~$ 

如何访问阵列?

推荐答案

具有不均匀键的对象数组在这里使事情变得有些棘手.走过.files后,您需要开始使用数组迭代[] 来访问这些元素,然后使用对象操作,例如 keys 更深入.

The array of objects with non-uniform keys is making things a little tricky here. Once you've gotten past .files you need to start using Array Iteration [] to access those elements and then use object operations like keys to go deeper.

在此情况下,此功能可能会有所帮助.它将扫描.files以查找具有与指定键匹配的键的对象,然后返回相应的值:

Here is a function which may help in this situation. It scans .files for an object with a key matching the specified key and then returns the corresponding value:

def getfile($k): .files[] | select(keys[] | .==$k) | .[$k];

如果jqtest包含示例数据,则命令

If jqtest contains the sample data the command

$ jq -M '
def getfile($k): .files[] | select(keys[] | .==$k) | .[$k];
getfile("BLOCK1").SUBBLOCK1.akey1
' jqtest

返回

"avalue1"

另一种方法是使用函数将.files[]转换为更有用的形式.例如

Another approach is to use a function to convert .files[] into a more useful form. e.g.

$ jq -M '
def files: reduce .files[] as $f ({}; ($f|keys[0]) as $k | .[$k] = $f[$k]) ;
files 
' jqtest

这将返回没有数组的更统一的结构

this returns a more uniform structure without arrays

{
  "BLOCK1": {
    "SUBBLOCK1": {
      "akey1": "avalue1",
      "bkey1": "bvalue1",
      "ckey1": "cvalue1"
    },
    "dkey1": "dvalue1",
    "key": "evalue1"
  },
  "BLOCK-2": ...

因此,您可以编写

files.BLOCK1.SUBBLOCK1

获得

{
  "akey1": "avalue1",
  "bkey1": "bvalue1",
  "ckey1": "cvalue1"
}

请注意,jq将在每次使用时重新评估files函数,因此以下形式可能更实用:

Note that jq will re-evaluate the files function with each use so the following form may be more practical:

  files as $files
| $files.BLOCK1.SUBBLOCK1

如果您发现此表示形式很有用,则可能要跳过该功能,而只需使用以下方法启动过滤器

If you find this representation useful you may want to skip the function and instead just start your filter with

.files = reduce .files[] as $f ({}; ($f|keys[0]) as $k | .[$k] = $f[$k])

例如

$ jq -M '
.files = reduce .files[] as $f ({}; ($f|keys[0]) as $k | .[$k] = $f[$k])
# more stuff goes here
' jqtest

将您的输入转换为

{
  "files": {
    "BLOCK1": {
      "SUBBLOCK1": {
        "akey1": "avalue1",
        "bkey1": "bvalue1",
        "ckey1": "cvalue1"
      },
      "dkey1": "dvalue1",
      "key": "evalue1"
    },
    "BLOCK-2": {
      "SUBBLOCK2": {
        "akey2": "avalue2",
        "bkey2": "bvalue2"
      },
      "ckey2": "cvalue2",
      "key": "dvalue2"
    },
    "BLOCK-A": {
      "SUBBLOCK2": {
        "akey2": "avalue2",
        "bkey2": "bvalue2"
      },
      "ckey2": "cvalue2",
      "key": "dvalue2"
    }
  },
  "NOBLOCK": "value",
  "key": "NOBLOCKvalue"
}

在此之后使您需要做的其他事情更容易

making whatever else you need to do after that easier

这篇关于无法让jq识别json文件中的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆