使用shell脚本

时间:2017-08-10 15:00:51

标签: json shell jq

我正在尝试使用jq。

解析shell脚本程序中的json文件

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
        }
    }
}

levelsArray DictionarieslevelDictionaries之一。每个级别都包含Array coursesDictionary,每个级别为Array,其中包含lessonlevels=$(jq ".items[0].playlists" data.json) for level in $levels do title=$($level | jq ".title") echo $title done 词典。

来自Swift,我发现jq的语法非常混乱,特别是将函数返回值赋给变量。这是我走了多远:

groups = (1, 2, 3, 4)
attrs = ('Referencia', 'Concepto', 'Cantidad', 'Precio', 'Descuento')
idx = (15, 22, 29, 38)

for group, index in zip(groups, idx):
    for i, attr in enumerate(attrs):
        getattr(self, 'line' + attr + str(i)).setText(utilidades.ensure_its_str(registro[i+index]))

这似乎根本不起作用。我想我的逻辑使用for循环在这里是完全错误的。有任何想法如何做到这一点?

1 个答案:

答案 0 :(得分:3)

将标题和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进行递归和发布平面(制表符分隔)列表的工作,并在bash中读取该列表。出于显而易见的原因,这只适用于内容不能包含标签的情况;如果你需要使用任意字符串(在bash可以存储的范围内),可以从jq生成NUL分隔的输出,但需要stedolan/jq#1271中讨论的解决方法之一

请参阅BashFAQ #1讨论我们在此处使用的技术,以便从jq的输出中读取制表符分隔的数据。