通过bash脚本更改json文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24942875/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:26:29  来源:igfitidea点击:

change json file by bash script

jsonbash

提问by user3155074

I need your help to solve the following problem: I have a JSON file that looks like this:

我需要您的帮助来解决以下问题:我有一个如下所示的 JSON 文件:

{
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}

how can I add and remove a new key (i.e "key4": "value4") by bash script? I see also the issue to add or remove a comma at the end of last key in the file before adding or removing the new one.

如何"key4": "value4"通过 bash 脚本添加和删​​除新密钥(即)?我还看到了在添加或删除新键之前在文件中最后一个键的末尾添加或删除逗号的问题。

Thank you

谢谢

回答by mklement0

Your best bet is to use a JSON CLIsuch as jq:

最好的选择是使用JSON CLIjq

  • On Debian-based systems such as Ubuntu, you can install it via sudo apt-get install jq
  • On macOS, with Homebrew (http://brew.sh/) installed, use brew install jq
  • 在基于 Debian 的系统(例如 Ubuntu)上,您可以通过以下方式安装它 sudo apt-get install jq
  • 在 macOS 上,安装Homebrew ( http://brew.sh/) 后,使用brew install jq

Examples, based on the following input string - output is to stdout:

示例,基于以下输入字符串 - 输出为stdout

jsonStr='{ "key1": "value1", "key2": "value2", "key3": "value3" }'

Remove "key3":

删除“key3”:

jq 'del(.key3)' <<<"$jsonStr"

Add property "key4" with value "value4":

添加值为“value4”的属性“key4”:

jq '. + { "key4": "value4" }' <<<"$jsonStr"

Change the value of existing property "key1" to "new-value1":

将现有属性“key1”的值更改为“new-value1”:

jq '.key1 = "new-value1"' <<<"$jsonStr"

A more robust alternative thanks, Lars Kiesow:
If you pass the new value with --arg, jqtakes care of properly escaping the value:

感谢Lars Kiesow一个更强大的替代方案 :
如果您使用 传递新值--arg,请jq注意正确转义该值:

jq '.key1 = $newVal' --arg newVal '3 " of rain' <<<"$jsonStr"


If you want to update a JSON file in place (conceptually speaking), using the example of deleting "key3":

如果要就地更新 JSON 文件(从概念上讲),以删除“key3”为例:

# Create test file.
echo '{ "key1": "value1", "key2": "value2", "key3": "value3" }' > test.json

# Remove "key3" and write results back to test.json (recreate it with result).
jq -c 'del(.key3)' test.json > tmp.$$.json && mv tmp.$$.json test.json

You cannot replace the input file directly, so the result is written to a temporary file that replaces the input file on success.

您不能直接替换输入文件,因此将结果写入一个临时文件,在成功时替换输入文件。

Note the -coption, which produces compact rather than pretty-printed JSON.

请注意该-c选项,它生成紧凑而不是漂亮打印的 JSON。

For all options and commands, see the manualat http://stedolan.github.io/jq/manual/.

对于所有选项和命令,请参阅手册http://stedolan.github.io/jq/manual/

回答by Lenny Markus

Not the answer for everyone, but if you already happen to have NodeJs installed in your system, you can use it to easily manipulate JSON.

不是每个人的答案,但如果您的系统中已经安装了 NodeJ,您可以使用它轻松操作 JSON。

eg:

例如:

#!/usr/bin/env bash
jsonFile=;

node > out_${jsonFile} <<EOF
//Read data
var data = require('./${jsonFile}');

//Manipulate data
delete data.key3
data.key4 = 'new value!';

//Output data
console.log(JSON.stringify(data));

EOF

Heck, if you onlyneed to do JSON manipulation and you have node (ie: You don't really need any other bash functionality) you could directly write a script using node as the interpreter:

哎呀,如果您需要进行 JSON 操作并且您有节点(即:您实际上不需要任何其他 bash 功能),您可以直接使用节点作为解释器编写脚本:

#! /usr/bin/env node
var data = require('./'+ process.argv[2]);
/*manipulate*/
console.log(JSON.stringify(data));

回答by Ben Chislett

Building off Lenny's answer, we can use node's -p option, which evaluates the given script and writes the output to stdout.

基于 Lenny 的回答,我们可以使用 node 的 -p 选项,它会评估给定的脚本并将输出写入stdout.

Using the spread operator for easy modification gives:

使用扩展运算符进行简单修改可以得到:

node -p "JSON.stringify({...require('./data.json'), key4: 'value4'}, null, 2)" > data.json

回答by Mila Nautikus

to change a file in place, use the spongecommand, like

要就地更改文件,请使用sponge命令,例如

cat file.json | jq '.path.to.key = $v' --arg v 'new value' | sponge file.json

回答by Reino

how can I add and remove a new key (i.e "key4": "value4") by bash script?

如何"key4": "value4"通过 bash 脚本添加和删​​除新密钥(即)?

Using a dedicated JSON tool, like Xidel, would be a better idea than to use pure Bash functions.

使用像Xidel这样的专用 JSON 工具比使用纯 Bash 函数更好。

Add a new attribute-value pair:

添加一个新的属性值对:

Dot notation:

点符号:

echo '{"a":1,"b":2,"c":3}' | xidel -s - -e '($json).d:=4'
{
  "d": 4,
  "a": 1,
  "b": 2,
  "c": 3
}

JSONiq:

JSONiq:

echo '{"a":1,"b":2,"c":3}' | xidel -s - -e '{|$json,{"d":4}|}'
{
  "a": 1,
  "b": 2,
  "c": 3,
  "d": 4
}

XQuery 3.1(requires Xidel 0.9.9-beta):

XQuery 3.1(需要Xidel 0.9.9-beta):

echo '{"a":1,"b":2,"c":3}' | xidel -s - -e 'map:put($json,"d",4)'
{
  "d": 4,
  "a": 1,
  "b": 2,
  "c": 3
}

echo '{"a":1,"b":2,"c":3}' | xidel -s - -e 'map:merge(($json,{"d":4}))'
{
  "a": 1,
  "b": 2,
  "c": 3,
  "d": 4
}

Remove the attribute-value pair "d":4:

删除属性值对"d":4

JSONiq:

JSONiq:

echo '{"a":1,"b":2,"c":3,"d":4}' | xidel -s - --xmlns:jnlib="http://jsoniq.org/function-library" -e 'jnlib:remove-keys($json,"d")'
{
  "a": 1,
  "b": 2,
  "c": 3
}

XQuery 3.1(requires Xidel 0.9.9-beta):

XQuery 3.1(需要Xidel 0.9.9-beta):

echo '{"a":1,"b":2,"c":3,"d":4}' | xidel -s - -e 'map:remove($json,"d")'
{
  "a": 1,
  "b": 2,
  "c": 3
}