代码之家  ›  专栏  ›  技术社区  ›  damjandd

在shell脚本中使用jq迭代JSON对象

  •  0
  • damjandd  · 技术社区  · 8 年前

    JSON结构如下所示:

    {
       "items":[
          {
             "playlists":[
                {
                   "title":"Level One Title",
                   "courses":[
                      {
                         "title":"Level One Course One Title",
                         "lessons":[
                            {
                               "title":"lesson 1 title",
                               "url":"lesson 1 url"
                            },
                            {
                               "title":"lesson 2 title",
                               "url":"lesson 2 url"
                            }
                         ]
                      },
                      {
                         "title":"Level One Course Two Title",
                         "lessons":[
                            {
                               "title":"lesson 1 title",
                               "url":"lesson 1 url"
                            },
                            {
                               "title":"lesson 2 title",
                               "url":"lesson 2 url"
                            }
                         ]
                      }
                   ]
                },
                {
                   "title":"Level Two Title",
                   "courses":[
                      {
                         "title":"Level Two Course One Title",
                         "lessons":[
                            {
                               "title":"lesson 1 title",
                               "url":"lesson 1 url"
                            },
                            {
                               "title":"lesson 2 title",
                               "url":"lesson 2 url"
                            }
                         ]
                      },
                      {
                         "title":"Level Two Course Two Title",
                         "lessons":[
                            {
                               "title":"lesson 1 title",
                               "url":"lesson 1 url"
                            },
                            {
                               "title":"lesson 2 title",
                               "url":"lesson 2 url"
                            }
                         ]
                      }
                   ]
                }
             ]
          }
       ]
    }
    

    由于我是一名iOS开发者,我已经编写了一段模拟的Swift代码,可以实现我想要的。看起来是这样的:

    for level in levels {
        let title = level["title"]
        //TODO: create a folder with title and set as pwd
        for course in level["courses"] {
            let courseTitle = course["title"]
            //TODO: create a folder with title and set as pwd
            for lesson in course["lessons"] {
                let title = lesson["title"]
                let videoURL = lesson["url"]
                //TODO: download video in current folder with title
            }
        }
    }
    

    levels Array 属于 Dictionaries , level 是其中之一 .每个级别包含一个 属于 courses Dictionary ,包含 大堆 lesson 字典。

    levels=$(jq ".items[0].playlists" data.json)
    for level in $levels
    do
        title=$($level | jq ".title")
        echo $title
    done
    

    这似乎根本不起作用。我想我在这里使用循环的逻辑是完全错误的。你知道怎么做吗?

    1 回复  |  直到 8 年前
        1
  •  3
  •   Charles Duffy    8 年前

    将标题和URL提取到不同shell变量中的代码可能如下所示:

    jq_program='
    .items[].playlists[]            # we only care about playlist contents
    | .title as $level_title        # store the level title before recursing
    | .courses[]                    # ...into elements of the array in .courses...
    | .title as $course_title       # repeat to store the course title
    | .lessons[]                    # ...before recursing into the lesson...
    # ...and emitting the stored level and course titles, plus the lesson title and url
    | [$level_title, $course_title, .title, .url] | @tsv                              
    '
    
    while IFS=$'\t' read -r level_title course_title lesson_title lesson_url <&3; do
      mkdir -p -- "$level_title/$course_title"
      ## For test purposes, just store the URL in the file
      printf '%s\n' "$lesson_url" >"$level_title/$course_title/$lesson_title"
      ## If we had real data, we might instead be running something like:
      # curl -o "$level_title/$course_title/$lesson_title" "$lesson_url"
    done 3< <(jq -r "$jq_program" <input.json)
    

    这里,我们有 jq jq公司 ,但需要中讨论的解决方法之一 stedolan/jq#1271

    BashFAQ #1 讨论我们在这里使用的技术,从 jq公司