将JSON解析为shell脚本中的数组 [英] Parse JSON to array in a shell script

查看:858
本文介绍了将JSON解析为shell脚本中的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将Shell脚本中的JSON对象解析为数组.

I'm trying to parse a JSON object within a shell script into an array.

例如:[Amanda,25岁, http://mywebsite.com]

e.g.: [Amanda, 25, http://mywebsite.com]

JSON如下:

{
  "name"       : "Amanda", 
  "age"        : "25",
  "websiteurl" : "http://mywebsite.com"
}

我不想使用任何库,最好是可以使用正则表达式或grep.我已经完成了:

I do not want to use any libraries, it would be best if I could use a regular expression or grep. I have done:

myfile.json | grep name

这给了我名字":阿曼达".我可以为文件中的每一行循环执行此操作,然后将其添加到数组中,但是我只需要右侧而不是整行.

This gives me "name" : "Amanda". I could do this in a loop for each line in the file, and add it to an array but I only need the right side and not the entire line.

推荐答案

如果您确实无法使用适当的JSON解析器,例如

If you really cannot use a proper JSON parser such as jq[1] , try an awk-based solution:

Bash 4.x:

readarray -t values < <(awk -F\" 'NF>=3 {print $4}' myfile.json)

Bash 3.x:

IFS=$'\n' read -d '' -ra values < <(awk -F\" 'NF>=3 {print $4}' myfile.json)

这会将所有属性存储在Bash数组${values[@]}中,您可以使用
declare -p values.

This stores all property values in Bash array ${values[@]}, which you can inspect with
declare -p values.

这些解决方案有局限性:

These solutions have limitations:

  • 每个属性必须位于单独的行上,
  • 所有值都必须用双引号引起来,
  • 不支持嵌入的转义双引号.

所有这些限制加强了建议使用正确的JSON解析器.

All these limitations reinforce the recommendation to use a proper JSON parser.

注意:以下替代解决方案使用Bash 4.x + readarray -t values命令,但它们也可以与Bash 3.x替代产品IFS=$'\n' read -d '' -ra values一起使用.

Note: The following alternative solutions use the Bash 4.x+ readarray -t values command, but they also work with the Bash 3.x alternative, IFS=$'\n' read -d '' -ra values.

grep + cut组合:单个grep命令将不起作用(除非您使用 GNU grep-参见下文),但是添加cut帮助:

grep + cut combination: A single grep command won't do (unless you use GNU grep - see below), but adding cut helps:

readarray -t values < <(grep '"' myfile.json | cut -d '"' -f4)


GNU grep :使用-P支持PCRE,PCRE支持\K删除到目前为止所有匹配的内容(比外观更灵活的替代方法-断言后面的内容)以及前瞻性断言((?=...)):


GNU grep: Using -P to support PCREs, which support \K to drop everything matched so far (a more flexible alternative to a look-behind assertion) as well as look-ahead assertions ((?=...)):

readarray -t values < <(grep -Po ':\s*"\K.+(?="\s*,?\s*$)' myfile.json)


最后,这是一个纯Bash(3.x +)解决方案:

就性能而言,使之成为可行替代方案的原因是,在每次循环迭代中都不会调用任何外部实用程序;但是,对于较大的输入文件,基于外部实用程序的解决方案将更快.

What makes this a viable alternative in terms of performance is that no external utilities are called in each loop iteration; however, for larger input files, a solution based on external utilities will be much faster.

#!/usr/bin/env bash

declare -a values # declare the array                                                                                                                                                                  

# Read each line and use regex parsing (with Bash's `=~` operator)
# to extract the value.
while read -r line; do
  # Extract the value from between the double quotes
  # and add it to the array.
  [[ $line =~ :[[:blank:]]+\"(.*)\" ]] && values+=( "${BASH_REMATCH[1]}" )
done < myfile.json                                                                                                                                          

declare -p values # print the array


[1]以下是基于jq的可靠解决方案的外观(Bash 4.x):
readarray -t values < <(jq -r '.[]' myfile.json)


[1] Here's what a robust jq-based solution would look like (Bash 4.x):
readarray -t values < <(jq -r '.[]' myfile.json)

这篇关于将JSON解析为shell脚本中的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆