我只想更改文件的某个部分,如下所示:
{
"Section_A": {
"ws/abc-Location01": 24,
"ws/abc-Location02": 67,
"ws/abc-Location03: 101,
},
"Section_B": {
"ws/abc-Location01": 33,
"ws/abc-Location02": 59,
"ws/abc-Location03: 92,
}
}
我想根据shell脚本中位置名称与数组的匹配,更改仅B节中字段2中的数值。
例如,如果我的脚本中的数组中存在ws/abc-Location01
,则不应更改其值,否则应将其值更改为file1.txt中第2个字段的值,其中第1个字段包含位置名称(如ws/abc-Location01
)
我不确定如何解决这个问题,因为每个部分都会出现一个给定的位置名称。那么如何告诉我的脚本忽略A部分,C部分等,只是改变B部分的值?
答案 0 :(得分:0)
使用jq:
# list all the keys in Section B into a bash array
keys_str=$(jq --raw-output '.["Section_B"] | keys | @sh' <test.json)
eval "keys_arr=( $keys_str )"
# determine which keys are not present in your other array
# assumes that the other array is associative for sanity
keys_to_change=( )
for key in "${keys_arr[@]}"; do
[[ ${other_array[$key]} ]] || keys_to_change+=( "$key" )
done
for key in "${keys_to_change[@]}"; do
# this is the inefficient way to do this, but it's much less code / easier
# to show; in this case, we're changing everything listed to 0, since you
# don't specify how you want to change them more precisely.
jq --arg key "$key" \
'.["Section_B"][$key] = 0' \
<test.json >test.json.new \
&& mv test.json.new test.json
done
一般来说,语法识别工具是你最好的选择 - 就像人们提出有关XML的类似问题被告知要使用XMLStarlet或其他XPath引擎一样,使用正确的JSON解析器和生成器是进行编辑的正确方法。这可能需要安装额外的依赖项 - 但它确保您实际生成语法上有效的内容。
答案 1 :(得分:0)
假设您的文件是正确的JSON(它不是似乎在您的示例文件中是这种情况 - 但您在评论中确认了它),您最喜欢的脚本语言的几行应该是足够的。
就我自己而言,我使用了Python:
import sys
import json
data = json.load(sys.stdin)
data["Section_B"]["ws/abc-Location02"] = 9999
json.dump(data, sys.stdout,indent=True)
假设该文件存储为&#34; change.py&#34;
# Original data (proper JSON)
$ cat data.json
{
"Section_A": {
"ws/abc-Location01": 24,
"ws/abc-Location02": 67,
"ws/abc-Location03": 101
},
"Section_B": {
"ws/abc-Location01": 33,
"ws/abc-Location02": 59,
"ws/abc-Location03": 92
}
}
# Pipe original data to our filter
$ cat data.json | python change.py
{
"Section_A": {
"ws/abc-Location01": 24,
"ws/abc-Location02": 67,
"ws/abc-Location03": 101
},
"Section_B": {
"ws/abc-Location01": 33,
"ws/abc-Location02": 9999,
"ws/abc-Location03": 92
}
}
如果您想要一个仅限shell的解决方案,sed
可能就足够了:
cat data.json | sed '/Section_B/,/}/{/Location02/s/:[^,]*/ 9999/}'
这显然更短;但也更脆弱...... 从好的方面来说,这将处理类似JSON的文件以及正确的JSON(假设在您的示例中格式化)。