如何从包括父键的json数组中获取最新的日期键值对

时间:2019-04-28 07:49:35

标签: json jq

1)我正在尝试使用json的jq生成CSV文件。 2)我需要父键以及子数组中的一对键值对 3)哪个值具有最新日期,将成为结果键值对 4)需要根据该结果生成一个csv

这是我的json

{
    "students": [
        {
            "name": "Name1",
            "class": "parentClass1",
            "teacher": "teacher1",
            "attendance": [
                {
                    "key": "class1",
                    "value": "01-DEC-2018"
                },
                {
                    "key": "class1",
                    "value": "28-Nov-2018"
                },
                {
                    "key": "class1",
                    "value": "26-Oct-2018"
                }
            ]
        },
        {
            "name": "Name2",
            "class": "parentClass2",
            "teacher": "teacher2",
            "attendance": [
                {
                    "key": "class2",
                    "value": "05-DEC-2018"
                },
                {
                    "key": "class2",
                    "value": "25-Nov-2018"
                },
                {
                    "key": "class2",
                    "value": "20-Oct-2018"
                }
            ]
        }
    ]
}

我试图创建这样的csv并没有取得太大进展

jq  '.students[] | [.name, .class, attendance[].key,.properties[].value] | @csv ' main.json

以下是该json的预期CSV

Name         ParentClass        key         dateValue                                                                           Summary
Name1        parentClass1      class1       150 days ago(difference with today date with latest date i.e 01-DEC-2018 )         Teacher1.parentClass1
Name2        parentClass2      class2       150 days ago(difference with today date with latest date i.e 05-DEC-2018 )         Teacher2.parentClass2

2 个答案:

答案 0 :(得分:3)

使用strptime解析日期,并将结果分配给 value s,因此您可以使用max_by获得最新的出勤率。使用mktime value 转换为自大纪元以来的秒数,从 now 中减去它,除以24 * 60 * 60,得到自此以来的天数。

$ jq -r '
def days_since:
  (now - .) / 86400 | floor;
.students[]
| [ .name, .class ] +
  ( .attendance
    | map(.value |= strptime("%d-%b-%Y"))
    | max_by(.value)
    | [ .key, "\(.value | mktime | days_since) days ago" ]
  ) +
  [ .teacher + "." + .class ]
| @tsv' file
Name1   parentClass1    class1  148 days ago    teacher1.parentClass1
Name2   parentClass2    class2  144 days ago    teacher2.parentClass2

请注意,此解决方案不处理夏令时更改。

答案 1 :(得分:1)

出于生产目的jq在这里不能使用,因为它不允许执行夏令时安全日期计算。

我之所以使用Python,是因为它允许执行夏令时安全的日期计算,默认情况下具有json支持,并且安装在大多数UNIX派生产品上。

#!/usr/bin/env python
import argparse
from datetime import datetime
import json


def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('filename')
    return parser.parse_args()


def main():
    args = parse_args()
    with open(args.filename) as file_desc:
        data = json.load(file_desc)

    print('Name\tParentClass\tkey\tdateValue')

    today = datetime.today()
    for record in data['students']:
        for a in record['attendance']:
            date = datetime.strptime(a['value'], '%d-%b-%Y')
            a['since'] = (today - date).days
        last = sorted(record['attendance'], key=lambda x: x['since'])[0]
        print('\t'.join([
            record['name'],
            record['class'],
            last['key'],
            '{} days ago'.format(last['since']),
            '{}.{}'.format(record['teacher'], record['class']),
        ]))


if __name__ == '__main__':
    main()

输出(在撰写此答案的当天):

Name    ParentClass Key DateValue   Summary
Name1   parentClass1    class1  148 days ago    teacher1.parentClass1
Name2   parentClass2    class2  144 days ago    teacher2.parentClass2
相关问题