就地使用 jq 修改 json 中的键值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42716734/
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 18:49:00  来源:igfitidea点击:

Modify a key-value in a json using jq in-place

jsonbashshelljq

提问by wolfsbane

I have a json in which I want to modify a particular value but the terminal always displays the json with the modified value but it does not actually change the value in the particular file. Sample json:

我有一个 json,我想在其中修改特定值,但终端总是显示带有修改值的 json,但它实际上并没有更改特定文件中的值。示例json:

{
   name: 'abcd',
   age: 30,
   address: 'abc'
}

I want to change the value of address in the file itself but so far I've been unable to do so. I tried using:

我想更改文件本身中地址的值,但到目前为止我一直无法这样做。我尝试使用:

jq '.address = "abcde"' test.json

but it didn't work. Any suggestions?

但它没有用。有什么建议?

回答by chepner

Use a temporary file; it's what any program that claims to do in-place editing is doing.

使用临时文件;这就是任何声称可以进行就地编辑的程序正在做的事情。

tmp=$(mktemp)
jq '.address = "abcde"' test.json > "$tmp" && mv "$tmp" test.json

If the address isn't hard-coded, pass the correct address via a jqargument:

如果地址不是硬编码的,请通过jq参数传递正确的地址:

address=abcde
jq --arg a "$address" '.address = $a' test.json > "$tmp" && mv "$tmp" test.json

回答by zeppelin

AFAIK jqdoes not support in-place editing, so you must redirect to a temporary file first and then replace your original file with it, or use spongeutility from the moreutils package, like that:

AFAIKjq不支持就地编辑,因此您必须先重定向到临时文件,然后用它替换原始文件,或者使用spongemoreutils 包中的实用程序,如下所示:

jq '.address = "abcde"' test.json|sponge test.json

There are other techniques to "redirect to the same file", like saving your output in a variable e.t.c. "Unix & Linux StackExchange" is a good place to start, if you want to learn more about this.

还有其他技术可以“重定向到同一文件”,例如将输出保存在变量中等,“Unix 和 Linux StackExchange”是一个很好的起点,如果您想了解更多信息。

回答by Rafal Kita

Just to add to chepner answer and if you want it in a shell script.

只是为了添加到 chepner 答案,如果你想在 shell 脚本中使用它。

test.json

测试文件

{
  "name": "abcd",
  "age": 30,
  "address": "abc"
}

script.sh

脚本文件

#!/bin/bash
address="abcde"
age=40

# Strings:
jq --arg a "${address}" '.address = $a' test.json > "tmp" && mv "tmp" test.json

# Integers:
jq --argjson a "${age}" '.age = $a' test.json > "tmp" && mv "tmp" test.json

回答by Andy

Temp files add more complexity when not needed (unless you are truly dealing with JSON files so large you cannot fit them in memory (GB to 100's of GB or TB, depending on how much RAM/parallelism you have)

临时文件在不需要时会增加更多的复杂性(除非您真正处理 JSON 文件太大以至于无法将它们放入内存中(GB 到 100 的 GB 或 TB,取决于您拥有多少 RAM/并行度)

The Pure bash way.

纯粹的 bash 方式。

contents="$(jq '.address = "abcde"' test.json)" && \
echo "${contents}" > test.json

Pros

优点

  • No temp file to juggle
  • Pure bash
  • Don't need an admin to install sponge, which is not installed by default
  • Simpler
  • 没有临时文件可以处理
  • 纯粹的 bash
  • 不需要管理员安装sponge,默认不安装
  • 更简单

Note: this can not be combined as "one command", since beforeas the command starts executing, the redirection starts, and empties the file, hence two separate commands.

注意:这不能组合为“一个命令”,因为命令开始执行之前,重定向开始并清空文件,因此是两个单独的命令。