由于某些极端的原因,我不能使用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