在shell脚本中将JSON解析为数组
我试图将shell脚本中的JSON对象解析为数组 e、 g.:[Amanda,25岁 JSON看起来像:在shell脚本中将JSON解析为数组,json,bash,shell,parsing,Json,Bash,Shell,Parsing,我试图将shell脚本中的JSON对象解析为数组 e、 g.:[Amanda,25岁 JSON看起来像: { "name" : "Amanda", "age" : "25", "websiteurl" : "http://mywebsite.com" } 我不想使用任何库,最好使用正则表达式或grep。我已经完成了: myfile.json | grep name 这给了我“name”:“Amanda”。我可以在循环中为文件中的每一行执行此操作,并将其
{
"name" : "Amanda",
"age" : "25",
"websiteurl" : "http://mywebsite.com"
}
我不想使用任何库,最好使用正则表达式或grep。我已经完成了:
myfile.json | grep name
这给了我“name”:“Amanda”。我可以在循环中为文件中的每一行执行此操作,并将其添加到数组中,但我只需要右边,而不需要整行。如果您确实无法使用正确的JSON解析器,如[1] ,尝试基于awk的解决方案
Bash 4.x:
readarray -t values < <(awk -F\" 'NF>=3 {print $4}' myfile.json)
GNUgrep
:使用-p
支持PCRE,PCRE支持\K
删除迄今为止匹配的所有内容(一种更灵活的后视断言替代方法)以及前瞻断言((?=…)
):
readarray-t值<您可以使用sed一行程序来实现这一点:
array=( $(sed -n "/{/,/}/{s/[^:]*:[[:blank:]]*//p;}" json ) )
结果:
$ echo ${array[@]}
"Amanda" "25" "http://mywebsite.com"
$ echo ${array[@]}
Amanda 25 http://mywebsite.com
如果您不需要/不想要引号,则以下sed将删除它们:
array=( $(sed -n '/{/,/}/{s/[^:]*:[^"]*"\([^"]*\).*/\1/p;}' json) )
结果:
$ echo ${array[@]}
"Amanda" "25" "http://mywebsite.com"
$ echo ${array[@]}
Amanda 25 http://mywebsite.com
如果您有多个条目,例如
$ cat json
{
"name" : "Amanda"
"age" : "25"
"websiteurl" : "http://mywebsite.com"
}
{
"name" : "samantha"
"age" : "31"
"websiteurl" : "http://anotherwebsite.org"
}
$ echo ${array[@]}
Amanda 25 http://mywebsite.com samantha 31 http://anotherwebsite.org
更新:
正如mklement0在评论中指出的,如果文件包含嵌入的空白,例如,“name”:“Amanda lastname”
。在这种情况下,Amanda
和lastname
都将分别读取到单独的数组字段中。为了避免这种情况,您可以使用readarray
,例如
readarray -t array < <(sed -n '/{/,/}/{s/[^:]*:[^"]*"\([^"]*\).*/\1/p;}' json2)
readarray-t array
paste -s <(jq '.files[].name' YourJsonString) <(jq '.files[].age' YourJsonString) <( jq '.files[].websiteurl' YourJsonString)
paste-s为此使用jq
。看看这个问题,并告诉我们您在解决这个问题上的一些努力。这个cat myfile.json | grep name | cut-d':'-f2
可能会有所帮助。@sjssam:链接问题的公认答案表明jq
使用得很好,但使用了一种错误的方法将其输出读入shell数组(至少在写这篇文章的时候-发表了评论)。我假设不是[Amanda,25,http://mywebsite.com]
你的意思是(“Amanda”25“http://mywebsite.com”
;后者是bash的数组语法实际上的样子。(或者,如declare-p array
所示,也可以按如下方式打印:declare-a array='([0]=“Amanda”[1]=“25”[2]=”http://mywebsite.com“”“
)请不要将命令输出解析为具有数组=($(…)
(即使它恰好与示例输入一起工作)的数组:它与嵌入的空格不符,可能会导致意外的全局搜索。@mklement0您能举一个例子,说明发生意外全局搜索时示例文件的内容必须是什么样子吗?@mklement0我不确定为什么全局搜索以前不匹配。可能是因为我操纵了IFS
在测试的某个时候。但是,在重新启动shell之后,球确实发生了。我会更新我的答案来解决这个问题。谢谢。请考虑编辑你的修正来实际地回答问题,而不是最后的补遗;否则,试图回答这个问题的人更可能使用这个错误。代码不比。(代码<回声$ {数组[@ ] } /代码>也是不好的形式——即使<代码>数组=(“hello”)“测试*示例”“Word”)/<代码>,它将不会打印为三个单独的元素,尽管内容被正确地存储在该方式中。请考虑<代码> Prtff '%s\n '“${Sale[@ ] }”/>代码>,与引号一起)。
readarray -t array < <(sed -n '/{/,/}/{s/[^:]*:[^"]*"\([^"]*\).*/\1/p;}' json2)
paste -s <(jq '.files[].name' YourJsonString) <(jq '.files[].age' YourJsonString) <( jq '.files[].websiteurl' YourJsonString)