我正在创建一个Bash脚本来解析网页上的空气污染水平:http://aqicn.org/city/beijing/m/
文件中有很多内容,但这是相关的部分:
“iaqi”:[{“p”:“"v":59,21,112,”,pm25“I”:“北京pm25”(细颗粒物),由美国驻北京大使馆空气质量监测仪(\u7f8e\u56fd\u9a7b\u5317\u4eac\u5927\u4f7f\u9986\u7a7a\u6c14\u8d28\u91cf\u76d1\u6d4b).测量。值由0 00b5g/m3换算成空气质量指数。“},{"p":" pm10 ","v":15,5,69,”I“:”北京空气可吸入颗粒物“,北京环境保护监测中心测量。
我希望脚本解析和显示两个数字:当前的PM2.5和PM10级别(上段中的粗体中的数字)。
CITY="beijing"
AQIDATA=$(wget -q 0 http://aqicn.org/city/$CITY/m/ -O -)
PM25=$(awk -v FS="(\"p\":\"pm25\",\"v\":\\\[|,[0-9]+)" '{print $2}' <<< $AQIDATA)
PM100=$(awk -v FS="(\"p\":\"pm10\",\"v\":\\\[|,[0-9]+)" '{print $2}' <<< $AQIDATA)
echo $PM25 $PM100即使我可以正确地显示PM2.5级别,也不能显示PM10级别。我不明白为什么,因为字符串是相似的。
有谁能解释清楚吗?
发布于 2016-02-22 03:28:28
以下方法基于两个步骤:
(1)提取相关JSON;
(2)使用JSON感知工具--这里是jq --从JSON中提取相关信息。
(1)理想情况下,web服务将提供允许直接获取JSON的JSON,但由于您的URL是用于使用浏览器查看的,因此需要某种形式的屏幕抓取。这种方法存在一定程度的脆性,所以这里我只提供一些目前起作用的东西:
wget -O - http://aqicn.org/city/beijing/m |
gawk 'BEGIN{RS="function"}
$1 ~/getAqiModel/ {
sub(/.*var model=/,"");
sub(/;return model;}/,"");
print}'(可以使用gawk或支持多字符RS的awk;如果您有另一个awk,则首先使用"function",例如:
sed $s/function/\\n/g‘#3反斜杠)
上面的输出可以管道到下面的jq命令,该命令执行上文(2)中所设想的筛选。
(2)
jq -c '.iaqi | .[]
| select(.p? =="pm25" or .p? =="pm10") | [.p, .v[0]]'结果:
["pm25",59]
["pm10",15]发布于 2016-02-22 03:16:35
我认为您的问题是,您有一个单行HTML文件,其中包含一个包含变量的脚本,该变量包含您要查找的数据。
您的字段分隔符是、、"p":"pm100", "v":[、或、逗号和一些数字。
对于pm25来说,这是可行的,因为它是第一个,并且在它之前没有发生,21或类似的事情。
然而,对于pm10,有一些是与pm25相关的。因此,第二个字段包含,21和,112之间的空字符串。
@karakfa的黑客攻击似乎奏效了--但他并没有很好地解释为什么会起作用。
他所做的就是使用awk的记录分隔符(通常是换行符),并将其设置为:、,或[中的任何一个。因此,在您的示例中,其中一个记录将是"pm25",因为它前面有一个冒号,它是分隔符,后面是一个逗号,也是一个分隔符。
一旦它命中匹配的内容("pm25"),它将一个计数器设置为4。然后,对于这个记录和下一个记录,它会对此计数器进行计数。"pm25"本身,"v",:和[之间的空字符串,当用要输出的数字命中记录时,最终到达一个字符串:4 && ! 3为false,3 && ! 2为false,2 && ! 1为false,但1 && ! 0为真。由于没有执行块,awk只是打印这个记录,这是您想要的值。
更健壮的工作可能是使用xpath查找脚本,然后使用一些json解析器或类似的方法来获得值。
发布于 2016-02-22 01:30:32
awk去营救!
如果有必要,您可以使用这种使用手工分隔符的智能计数器的方式。设置RS,而不是FS,会在字段中循环传输,以使其自身具有awk特性。多字符RS并不适用于所有的awk (gawk支持它)。
$ awk -v RS='[:,[]' '$0=="\"pm25\""{c=4} c&&!--c' file
59
$ awk -v RS='[:,[]' '$0=="\"pm10\""{c=4} c&&!--c' file
15https://stackoverflow.com/questions/35543915
复制相似问题