[英]Read a json file and grep a string from matching pattern using bash
I am trying to parse below big json file using bash 我正在尝试使用bash解析下面的大json文件
//part of json file
{"name": "Jenkins", "version": "Jenkins-2.22"},
{"name": "FitNesse", "version": "FitNesse-2.1"},
{"name": "Quint","version": "Quint-2.12"},
{"name": "Otto","version": "Otto-1.0"},
{"name": "Gradle","version": "Gradle-1.1"}
I am able read the line matching 'version' from json file 我可以从json文件中读取匹配“版本”的行
while read line; do
if [[ $line =~ "version" ]] ; then
echo $line; fi
done < $manifestfile
I want to store the values[Jenkins-2.22, FitNesse-2.1, Quint-2.12, Otto-1.0, Gradle-1.1] in array in my while loop 我想将值[Jenkins-2.22,FitNesse-2.1,Quint-2.12,Otto-1.0,Gradle-1.1]存储在我的while循环中的数组中
need help with tweaking my above code 在调整上面的代码时需要帮助
Assuming that the sample input above is inside a JSON array in file file.json
, ie: 假设上面的示例输入在文件
file.json
的JSON 数组中,即:
[
{"name": "Jenkins", "version": "Jenkins-2.22"},
{"name": "FitNesse", "version": "FitNesse-2.1"},
{"name": "Quint","version": "Quint-2.12"},
{"name": "Otto","version": "Otto-1.0"},
{"name": "Gradle","version": "Gradle-1.1"}
]
Note: The only change required to make the commands below work in Bash 3.x too is to replace readarray -t versions
with IFS=$'\\n' read -d '' -ra versions
注意:要使以下命令在Bash 3.x中也起作用,唯一需要做的更改就是用
IFS=$'\\n' read -d '' -ra versions
readarray -t versions
IFS=$'\\n' read -d '' -ra versions
readarray -t versions
替换readarray -t versions
IFS=$'\\n' read -d '' -ra versions
jq
: jq
: jq
must be installed first, but that's well worth the effort, if feasible: it enables sophisticated, robust JSON parsing . 必须首先安装
jq
,但如果可行,这是值得的,它很值得:可以进行复杂的,健壮的JSON解析 。
# Extract the version numbers and read them into a Bash array.
readarray -t versions < <(jq -r '.[].version' file.json)
# Print the array.
printf '%s\n' "${versions[@]}"
The above yields: 以上收益:
Jenkins-2.22
FitNesse-2.1
Quint-2.12
Otto-1.0
Gradle-1.1
awk
: awk
: If you cannot install jq
, the following awk
solution is an alternative, but note that it is much less robust and relies on the JSON to be formatted exactly as above . 如果您无法安装
jq
,则可以使用以下awk
解决方案,但请注意,该解决方案的健壮性要差得多 ,它依赖于JSON的格式完全如上所述 。
This warning applies to any solution using standard utilities ( awk
, grep
, sed
, ...) - only a dedicated JSON parser will work robustly . 此警告适用于任何解决方案使用标准工具(
awk
, grep
, sed
,...) - 唯一一个专门的JSON解析器将稳健运行 。
readarray -t versions < <(awk -F\" 'NF>1 { print $(NF-1) }' file.json)
# Print the array.
printf '%s\n' "${versions[@]}"
sed -n 's/.*"\([^"]*\)"}.*/\1/p' <file>
jq is a proper tool to manipulate JSON data in Unix shell. jq是在Unix shell中处理JSON数据的合适工具。
Let's say test.json
file contains: 假设
test.json
文件包含:
[
{"name": "Jenkins", "version": "Jenkins-2.22"},
{"name": "FitNesse", "version": "FitNesse-2.1"},
{"name": "Quint","version": "Quint-2.12"},
{"name": "Otto","version": "Otto-1.0"},
{"name": "Gradle","version": "Gradle-1.1"}
]
test_json.sh script (simplified version): test_json.sh脚本(简化版):
#!/bin/bash
versions=$(jq '.[] | .version' test.json)
versions_arr=($versions) # contains an array of `version` key values
I must warn that the above approach ($versions)
(creating an array upon string splitting) may fail if the string $versions
has globbing characters in it. 我必须警告 ,如果字符串
$versions
包含乱码 ,则上述方法($versions)
(在字符串拆分后创建数组)可能会失败 。
The more "steady" approach would be using built-in read
command with -a
option to read the data wordwise into the specified array: 更“稳定”的方法是将内置的
read
命令与-a
选项一起使用,以将字数据读入指定数组:
test_json.sh script ("steady" version): test_json.sh脚本(“稳定”版本):
#!/bin/bash
versions=$(jq '.[] | .version' test.json)
read -a versions_arr <<< $versions # read `version` key values into array
Now, versions_arr
is an array of version
key values. 现在,
versions_arr
是version
键值的数组。
To print for eg the second array value you would do: 要打印第二个数组值,您可以执行以下操作:
echo ${versions_arr[1]}
The output: 输出:
"FitNesse-2.1"
Use JQ for parsing your Json easily, just install JQ, then use : 使用JQ轻松解析您的Json,只需安装JQ,然后使用:
if you have a json array, and in every element you have the field version, you can use : 如果您有json数组,并且在每个元素中都有字段版本,则可以使用:
cat myJsonFile | jq '.[].version'
That will return a list of versions 这将返回版本列表
If you want to process line by line use 如果要逐行处理
while read line; do
if [[ $line =~ "version" ]] ; then
echo $line | jq .[] | jq ."version" ; fi
done < $manifestfile
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.