我有一个 JSON 文件,正在读入 bash 脚本,并且想在每个键前面添加一个固定字符串。
json_文件:
{"key_1": 12, "key_2": 34, "key_3": 56}
通过将字符串添加x_
到每个键来更新此数据的最简洁方法是什么?
例如,
{"x_key_1": 12, "x_key_2": 34, "x_key_3": 56}
答案1
您可以使用 JSON 解析器来jq
解析您的 JSON 文件。这样做的优点是,无论其形状如何,都可以处理有效的 JSON:
jq 'with_entries(.key |= "x_" + .)' <file.json
输入
{"key_1": 12, "key_2": 34, "key_3": 56}
输出
{
"x_key_1": 12,
"x_key_2": 34,
"x_key_3": 56
}
您可以使用以下命令将 JSON 保留在一行中jq -c …
:
{"x_key_1":12,"x_key_2":34,"x_key_3":56}
该解决方案在文档中作为示例显示jq
- 查看man jq
并搜索with_entries
- 但由于它是参考文档,因此很难找到您不知道如何描述的内容。
答案2
从字面上理解标题中的问题,以下内容将一些用户提供的字符串递归地附加到输入文档中的所有键:
jq --arg prefix x_ '
walk(
if type == "object" then
with_entries(.key = $prefix + .key)
else . end
)' file
密钥的更新类似于罗艾玛的回答,但不使用更新运算符。前缀字符串也在命令行上给出,而不是硬编码的字符串。
测试运行:
$ cat file
{
"key_1": 12,
"key_2": 34,
"key_3": [
{
"key_1": "{\"key_A\":123}",
"key_2": 34,
"key_3": 56
},
{
"key_1": "{\"key_A\":123}",
"key_2": 34,
"key_3": 56
}
]
}
$ jq --arg prefix x_ 'walk(if type == "object" then with_entries(.key = $prefix + .key) else . end)' file
{
"x_key_1": 12,
"x_key_2": 34,
"x_key_3": [
{
"x_key_1": "{\"key_A\":123}",
"x_key_2": 34,
"x_key_3": 56
},
{
"x_key_1": "{\"key_A\":123}",
"x_key_2": 34,
"x_key_3": 56
}
]
}
答案3
如果您的 json 格式是一行,那么以下内容应该有效:
sed -i 's/"\([^"]*\)":/"x_\1":/g' json_file.json
如果你的 json 格式如下所示:
{
"key_1": 1,
"key_2": "v2",
"key_3": 3
}
您可以使用sed
上面的命令,但也可以使用以下sed
更简单的命令:
sed -i 's/"\(.*\)":/"x_\1":/' json_file.json
笔记:如果您只有不具有以下模式的数字或字符串,则上述解决方案效果很好:
{ "key_1": "\"Sale\": foobar" }
// Or
{ "\"key_1\"": "\"Sale\": foobar" } // I think this case is less common
因此,正确编辑按键的最佳方法是使用罗艾玛的回答。我尝试了另一种可能的解决方案sed
(但我不确定是否存在其他可能失败的情况)。如果您的 json 文件如下所示:
{"key_1": "\"Sale\": foobar", "key_2": "\"3\":", "key_3": 56}
// Or maybe
{"key_1": "\"Sale:sale\": foobar", "key_2": "\"3\":", "key_3": 56}
你可以尝试使用:
sed -i 's/"\([^"\][^"\]*\)":/"x_\1":/g' json_file.json
但是,如果 json 文件如下所示,上面的命令将失败:
{"\"key_1\"": "\"Sale:\": foobar", "key_2": "\"3\":", "key_3": 56}
// If the json keys have \"somekey\" as their keys then the sed command will fail.
// So using sed for this task might be a little tricky for avoiding these problems.