(Mac 终端)sed 解析 JSON ...我做错了什么?

(Mac 终端)sed 解析 JSON ...我做错了什么?

在 Mac 终端中,我尝试从 JSON 响应中解析“名称”:

{"created_at":"2012-08-27T20:04:27Z","deleted_at":null,"id":21462840,"item_type":"video","name":"CastingBy-v12 mix.mov", "private":true,"redirect_url":null,"remote_url":"http://f.cl.ly/items/3D0P02b3e3p2I/CastingBy-v12%20mixed.mov","source":"Cloud/1.5.4 CFNetwork/520.4.3 Darwin/11.4.0 (x86_64) (MacPro5%2C1)","updated_at":"2012-08-27T20:13:38Z","view_counter":2,"href":"http:// /my.cl.ly/items/2840","icon":"http://my.cld.me/images/item-types/video.png","已订阅":true,"url":"http ://files.housenyc.com/1I3E2F3C","content_url":"http://files.eeehousenyc.com/1I3Q0Z1E2F3C/CastingBy-v12%20mixed.mov","download_url":"http://files.eeehousenyc .com/1I3Q0F3C/download/CastingBy-v12%20mixed.mov","gauge_id":null}

我在用着

sed 's/{.*?"name":"\(.+?\)".*/\1/'

但它返回整个字符串。

我想让它返回

CastingBy-v12 mixed.mov

答案1

仅使用 sed 解析 json 与解析 HTML 一样有问题 - 简而言之:由于元素可以嵌入其他元素并且正则表达式不支持递归,因此仅使用正则表达式基本上不可能正确解析。

这里有一个解析和验证 json 的 PCRE 解决方案:https://stackoverflow.com/questions/2583472/regex-to-validate-json- 我还没有使用或测试过它,所以我必须相信作者的话它是有效的......PCRE 做了很多 sed 支持的基本或扩展正则表达式中没有的事情。

无论如何,IMO 你最好使用 perl 或 python 或 awk 以及这些语言的 json 解析库之一,或者专门的 json 解析工具 - 这里提到了几个:

https://stackoverflow.com/questions/3858671/unix-command-line-json-parser

它们中的任何一个都可用于从 JSON 输入中提取数据以在 shell 脚本中使用。或者您可以用该语言编写整个程序。

例如,将 json 数据通过管道传输到 python -mjson.tool 中会产生以下结果:

$ 回显“JSONDATAHERE”| python -m json.工具
{
    "content_url": "http://files.eeehousenyc.com/1I3Q0Z1E2F3C/CastingBy-v12%20mixed.mov",
    "创建时间": "2012-08-27T20:04:27Z",
    “deleted_at”:空,
    "download_url": "http://files.eeehousenyc.com/1I3Q0F3C/download/CastingBy-v12%20mixed.mov",
    “gauge_id”:空,
    “href”:“http://my.cl.ly/items/2840”,
    “图标”:“http://my.cld.me/images/item-types/video.png”,
    “身份证”:21462840,
    "item_type": "视频",
    "name": "CastingBy-v12 mix.mov",
    “私人”:真实,
    “redirect_url”:空,
    "remote_url": "http://f.cl.ly/items/3D0P02b3e3p2I/CastingBy-v12%20mixed.mov",
    "source": "Cloud/1.5.4 CFNetwork/520.4.3 Darwin/11.4.0 (x86_64) (MacPro5%2C1)",
    “已订阅”:真实,
    "updated_at": "2012-08-27T20:13:38Z",
    "url": "http://files.housenyc.com/1I3E2F3C",
    “视图计数器”:2
}

然后你可以像这样通过管道输入 sed :

$ echo "JSONDATAHERE" | python -m json.tool | sed -n -e '/"name":/ s/^.*"\(.*\)".*/\1/p'
CastingBy-v12 mixed.mov

依靠正则表达式的贪婪本质,sed 脚本提取包含 的任何行上倒数第二个字符"和最后一个字符之间的所有内容。 ""name":

答案2

这是您正在寻找的表达式:

sed -e 's/^.*"name":"\([^"]*\)".*$/\1/' infile

其结果是:

CastingBy-v12 mixed.mov

你的有几个错误:

  • 仅在贪婪表达式中sed可以使用:.*?.+?都是不正确的。
  • 必须+逃脱。
  • 用于[^"]*避免正则表达式匹配到字符串的最后一个双引号。

答案3

这并不能直接回答你的问题。但如果您需要定期执行此类操作,请考虑使用通用的编程语言,例如 Perl、Python、Ruby。

在 Ruby 中,您的解决方案是:

some_command_that_emits_json | ruby -e "require 'rubygems';require 'json'; output=JSON.parse(STDIN.gets); puts output['name']"

答案4

这是使用JSON模块执行此操作的一种方法perl

 json_producing_process | perl -MJSON -lne 'print from_json($_)->{name}'

相关内容