如何将多行 JSON 对象通过管道传输到单独的 python 调用中

How to pipe multi-line JSON Objects into separate python invocations

我知道在 shell 中将标准输入通过管道输送到下游进程的基础知识,只要每一行都被单独处理,或者作为一个单一的输入,我就可以让我的管道工作。

但是当我想读取 4 行标准输入,做一些处理,再读取 6 行,然后做同样的事情时,我对管道的理解有限就成了问题。

例如,在下面的管道中,每次 curl 调用都会产生未知数量的输出行,这些输出行构成一个 JSONObject:

cat geocodes.txt \
  | xargs  -I% -n 1 curl -s 'http://maps.googleapis.com/maps/api/geocode/json?latlng='%'&sensor=true' \
  | python -c "import json,sys;obj=json.load(sys.stdin);print obj['results'][0]['address_components'][3]['short_name'];"

我如何才能在每次 python 调用时恰好消耗一个 JSON 对象?请注意,我实际上在 Python 方面的经验可以忽略不计。我实际上对 Node.js 有更多经验(使用 Node.js 处理 JSON curl 输出会更好吗?)

Geocodes.txt 类似于:

51.5035705555556,-3.15153263888889
51.5035400277778,-3.15153477777778
51.5035285833333,-3.15150258333333
51.5033861111111,-3.15140833333333
51.5034980555556,-3.15146016666667
51.5035285833333,-3.15155505555556
51.5035362222222,-3.15156338888889
51.5035362222222,-3.15156338888889

编辑 我有一种讨厌的感觉,答案是你需要逐行阅读并在解析之前检查你是否有一个完整的对象。有没有一个功能可以帮我完成这些繁重的工作?

我相信这种方法会达到你想要的效果。首先,将 python 脚本保存在一个文件中,例如 my_script.py。然后执行以下操作:

cat geocodes.txt \
  | xargs  -I% sh -c "curl -s 'http://maps.googleapis.com/maps/api/geocode/json?latlng='%'&sensor=true' | python my_script.py"

其中 my_script.py 是:

import json,sys;obj=json.load(sys.stdin);print obj['results'][0]['address_components'][3]['short_name'];

输出:

Cardiff
Cardiff
Cardiff
Cardiff
Cardiff
Cardiff
Cardiff
Cardiff

我承认这看起来有点老套。


原始答案

我不是 bash 巫师,所以我的直觉是简单地做 Python 中的所有事情。以下脚本将在 Python 3:

中说明该方法
import urllib.request as request
import urllib.parse as parse
import json

serviceurl = "http://maps.googleapis.com/maps/api/geocode/json?"

with open("geocodes.txt") as f:
    for line in f:
        url = (serviceurl +
               parse.urlencode({'latlng':line, 'sensor':'true'}))
        with request.urlopen(url) as response:
            bytes_data = response.read()
        obj = json.loads(bytes_data.decode('utf-8'))
        print(obj['results'][0]['address_components'][3]['short_name'])

输出:

Cardiff
Cardiff
Cardiff
Cardiff
Cardiff
Cardiff
Cardiff
Cardiff

看看:

http://trentm.com/json/#FEATURE-Grouping

Grouping can be helpful for "one JSON object per line" formats or for things such as:

$ cat *.json | json -g ...

要安装:

sudo npm install -g json

我自己还没有尝试过,所以无法验证它是否有效,但可能是缺少 link 来做你想做的事(组 JSON)

您不需要 python 或 node.js。 jq是专门为json过滤UNIX风格设计的:

sudo apt-get install jq

然后:

cat geocodes.txt  \
  | xargs  -I% curl -s 'http://maps.googleapis.com/maps/api/geocode/json?latlng='%'&sensor=true'  \
  | jq --unbuffered '.results[0].formatted_address'

或者,如果您想对所有 JPG 文件执行此操作:

find -iname "**jpg" \
  | xargs -n 1 -d'\n' exiftool -q -n -p '$GPSLatitude,$GPSLongitude' 
  | xargs  -I% curl -s 'http://maps.googleapis.com/maps/api/geocode/json?latlng='%'&sensor=true'  
  | jq --unbuffered  '.results[0].formatted_address'