Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在shell脚本中将JSON解析为数组_Json_Bash_Shell_Parsing - Fatal编程技术网

在shell脚本中将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”。我可以在循环中为文件中的每一行执行此操作,并将其

我试图将shell脚本中的JSON对象解析为数组

e、 g.:[Amanda,25岁

JSON看起来像:

{
  "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)

GNU
grep
:使用
-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)