如何在外壳中没有jq的情况下从这个木偶元数据中提取"name"的值.json?



由于某些极端的原因,我不能使用jq或其他cli工具。我需要从匹配这个傀儡元数据json的任何json中提取"name"的值。格式。

json可能没有正确格式化和缩进,但将是有效的。也就是说,除了空格和换行符之外,回车可以插入到符合条件的位置。

注意,依赖数组中可能有"name"元素。

那么,如何仅使用标准unix命令和/或shell脚本提取值,而不安装任何应用程序,如jq或其他工具?

谢谢! !

{
  "name": "examplecorp-mymodule",
  "version": "0.0.1",
  "author": "Pat",
  "license": "Apache-2.0",
  "summary": "A module for a thing",
  "source": "https://github.com/examplecorp/examplecorp-mymodule",
  "project_page": "https://forge.puppetlabs.com/examplecorp/mymodule",
  "issues_url": "https://github.com/examplecorp/examplecorp-mymodule/issues",
  "tags": ["things", "stuff"],
  "operatingsystem_support": [
    {
    "operatingsystem":"RedHat",
    "operatingsystemrelease":[ "5.0", "6.0" ]
    },
    {
    "operatingsystem": "Ubuntu",
    "operatingsystemrelease": [ "12.04", "10.04" ]
    }
   ],
  "dependencies": [
    { "name": "puppetlabs/stdlib", "version_requirement": ">=3.2.0 <5.0.0" },
    { "name": "puppetlabs/firewall", "version_requirement": ">= 0.0.4" }
  ]
}

这是丑陋的,可怕的,可怕的,不是结构感知的,如果您的输入文件中有额外的内容看起来与您试图找到的内容相似,则会给您不正确的结果-但是…

#!/bin/bash
#      ^- NOT /bin/sh; shell-native regexes are a bash extension
contents=$(<in.json)
if [[ $contents =~ '"name":'[[:space:]]*'"'([^"]*)'"' ]]; then
  echo "Found name: ${BASH_REMATCH[1]}"
fi

现在,让我们来谈谈这个答案被打破的一些方式(使用jq会更好):

  • 查找第一个名称,即使它不是外层嵌套层的名称。也就是说,如果"dependencies": [ { "name": "puppetlabs/stdlib", "version_requirement": ">=3.2.0 <5.0.0" } ]出现在"name": "examplecorp-mymodule"之前,猜猜是哪个结果?(简单的解决方法涉及对空白/格式进行假设,因此不能针对相同数据的所有可能的JSON表达式进行证明)。
  • 它不会取消你的名字里面需要的内容,嗯,取消转义(想想包含符号编码为&foo;的名字)。
  • 它不支持多字节字符,因此不能保证输出与码点边界对齐。
  • 如果您的名称带有转义的"子序列…猜猜会发生什么?

等。它不像尝试用正则表达式解析XML那么糟糕(JSON更容易!),但仍然相当混乱。

这应该可以为您工作:

jq '.name' metadata.json

最新更新