簡體   English   中英

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

[英]Modify a key-value in a json using jq in-place

我有一個 json ,我想在其中修改特定值,但終端始終顯示 json 和修改后的值,但它實際上並沒有更改特定文件中的值。 樣品 json:

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

我想更改文件本身的地址值,但到目前為止我一直無法這樣做。 我嘗試使用:

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

但它沒有用。 有什么建議么?

使用臨時文件; 這就是任何聲稱可以進行就地編輯的程序正在做的事情。

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

如果地址不是硬編碼的,請通過jq參數傳遞正確的地址:

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

AFAIK jq不支持就地編輯,因此您必須先重定向到臨時文件,然后用它替換原始文件,或者使用 moreutils 包中的sponge實用程序,如下所示:

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

還有其他技術可以“重定向到同一文件”,例如將輸出保存在變量中等,“Unix 和 Linux StackExchange”是一個很好的起點,如果您想了解更多信息。

臨時文件在不需要時會增加更多的復雜性(除非您真正處理 JSON 文件太大以至於無法將它們放入內存中(GB 到 100 的 GB 或 TB,取決於您擁有多少 RAM/並行度)

純粹的 bash 方式。

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

優點

  • 沒有臨時文件可以處理
  • 純粹的 bash
  • 不需要管理員來安裝sponge ,默認情況下不安裝
  • 更簡單

注意:這不能組合為“一個命令”,因為重定向表達式的左側 (LHS) 運行之前開始,並且在運行jq之前開始重定向會錯誤地清空文件,因此是兩個單獨的命令。

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

測試文件

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

腳本文件

#!/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

這應該工作

address = aaaaa
echo $(jq --arg a "$address" '.address = ($a)' test.json) > test.json

無論出於何種原因,如果沒有回聲,它會生成一個 bin 文件,而我的 python 腳本無法解析它。

具有更改單個和多個值的嵌套 json 的示例。

配置文件

{
  "Parameters": {
    "Environment": "Prod",
    "InstanceType": "t2.micro",
    "AMIID": "ami-02d8e11",
    "ConfigRegion": "eu-west-1"
  }
}

使用以下命令,您可以編輯多個值。

tmp=$(mktemp)
jq '.Parameters.AMIID = "ami-02d8sdfsdf" | .Parameters.Environment = "QA"' config.json > "$tmp" && mv "$tmp" config.json

使用以下命令,您可以編輯單個值。

tmp=$(mktemp)
jq '.Parameters.AMIID = "ami-02d8sdfsdf"' config.json > "$tmp" && mv "$tmp" config.json

我不喜歡任何解決方案並創建了sde實用程序

pip install sde

然后你可以簡單地做:

sde address abcde test.json

我在這里這里采取了最好的幾個答案。

這使用名為actionname的參數作為文檔級別的name屬性分配的輸入。 ACTION_NAME 只是我想用作替換值的環境變量。

contents="$(jq --arg actionname ${ACTION_NAME} '.name = $actionname' ./${ACTION_NAME}/package.json)" && \
echo -E "${contents}" > ${ACTION_NAME}/package.json;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM