在Bash

时间:2017-06-10 11:19:15

标签: arrays json bash

美国海军天文台有一个API,可以输出一个包含日出和日落时间的JSON文件,其中包括here

Here is an example输出JSON文件:

{
"error":false,
"apiversion":"2.0.0",
"year":2017,
"month":6,
"day":10,
"dayofweek":"Saturday",
"datechanged":false,
"lon":130.000000,
"lat":30.000000,
"tz":0,

"sundata":[
            {"phen":"U", "time":"03:19"},
            {"phen":"S", "time":"10:21"},
            {"phen":"EC", "time":"10:48"},
            {"phen":"BC", "time":"19:51"},
            {"phen":"R", "time":"20:18"}],

"moondata":[
            {"phen":"R", "time":"10:49"},
            {"phen":"U", "time":"16:13"},
            {"phen":"S", "time":"21:36"}],

"prevsundata":[
            {"phen":"BC","time":"19:51"},
            {"phen":"R","time":"20:18"}],

"closestphase":{"phase":"Full Moon","date":"June 9, 2017","time":"13:09"},
"fracillum":"99%",
"curphase":"Waning Gibbous"
}

我使用JSON相对较新,但我明白在" sundata"之后的方括号中的所有内容是一个JSON数组(如果我错了,请纠正我)。所以我搜索了如何从JSON数组中获取值的说明,但没有成功。

我已使用以下文件将文件下载到我的系统:

wget -O usno.json "http://api.usno.navy.mil/rstt/oneday?ID=iOnTheSk&date=today&tz=0&coords=30,130"

我需要从这一行中提取时间(采用HH:MM格式):

    {"phen":"S", "time":"10:21"},

...然后用它来创建一个变量(稍后我将写入一个单独的文件)。

如果可能的话,我更愿意使用Bash,最好使用JSON解析器(例如 jq ),如果它更容易理解/实现。如果可能的话,我宁愿不使用Python(这是我之前读过的很多文章所建议的),因为我试图更加熟悉Bash。

我已经检查了很多不同的网页,包括Stack Overflow上的答案,但是没有一个网站专门覆盖了每行有两个键/值对的数组线(他们只解释了如何只使用它每行一对,遗憾的是上述文件结构不是什么。

具体来说,我已阅读这些文章,但它们并没有解决我的特定问题:

提前感谢任何想法。

旁注:我已经成功完成了一个复杂的150多行文字,其中包括" sed" s,#34; grep" s," awk&#34什么,但是很明显,如果有一个单线JSON原生解决方案更优雅,我更喜欢使用它,因为我需要尽可能减少功耗(&#&# 39;在电池供电的设备上运行)。 (附注:旁注:脚本太长了,因为我需要为JSON文件中的每一行执行此操作,而不仅仅是" S"值)

2 个答案:

答案 0 :(得分:4)

如果您已经拥有jq,则可以通过以下方式轻松选择所需时间:

sun_time=$(jq '.sundata[] | select(.phen == "S").time' usno.json)
echo $sun_time
# "10:21"

答案 1 :(得分:0)

如果你必须使用"常规" bash命令(实际上,使用jq):

wget -O - "http://api.usno.navy.mil/rstt/oneday?ID=iOnTheSk&date=today&tz=0&coords=30,130" \
    | sed -n '/^"sundata":/,/}],$/p' \
    | sed -n -e '/"phen":"S"/{s/^.*"time":"//'\;s/...$//\;p} 

示例:

$ wget -O - "http://api.usno.navy.mil/rstt/oneday?ID=iOnTheSk&date=today&tz=0&coords=30,130" | sed -n '/^"sundata":/,/}],$/p' | sed -n -e '/"phen":"S"/{s/^.*"time":"//'\;s/...$//\;p} 
--2017-06-10 08:02:46--  http://api.usno.navy.mil/rstt/oneday?ID=iOnTheSk&date=today&tz=0&coords=30,130
Resolving api.usno.navy.mil (api.usno.navy.mil)... 199.211.133.93
Connecting to api.usno.navy.mil (api.usno.navy.mil)|199.211.133.93|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/json]
Saving to: ‘STDOUT’

-                            [ <=>                              ]     753  --.-KB/s    in 0s      

2017-06-10 08:02:47 (42.6 MB/s) - written to stdout [753]

10:21