91

特定の条件で更新する必要があるjsonファイルがあります。

サンプル json

{
   "Actions" : [
      {
         "value" : "1",
         "properties" : {
            "name" : "abc",
            "age" : "2",
            "other ": "test1"
          }
      },
      {
         "value" : "2",
         "properties" : {
            "name" : "def",
            "age" : "3",
            "other" : "test2"
          }
      }
   ]
}

以下に示すように、Jqを使用して値と更​​新を一致させるスクリプトを作成しています

cat sample.json |  jq '.Actions[] | select (.properties.age == "3") .properties.other = "no-test"'

出力 (端末に出力)

{
  "value": "1",
  "properties": {
    "name": "abc",
    "age": "2",
    "other ": "test1"
  }
}
{
  "value": "2",
  "properties": {
    "name": "def",
    "age": "3",
    "other": "no-test"
  }
}

このコマンドは必要な変更を行いますが、json 全体をターミナルに出力し、ファイル自体は変更しません。

jq でファイルを直接変更するオプションがあるかどうかをお知らせください (sed -i と同様)。

4

8 に答える 8

63

この投稿では、sed の「-i」オプションに相当するものがないこと、特に次の状況についての質問に対処します。

たくさんのファイルがあり、それぞれを個別のファイルに書き込むのは簡単ではありません。

少なくとも Mac や Linux などの環境で作業している場合は、いくつかのオプションがあります。それらの長所と短所については http://backreference.org/2011/01/29/in-place-editing-of-files/で説明されて いるので、ここでは 3 つの手法だけに焦点を当てます。

1 つは、次の行に沿って単純に「&&」を使用することです。

jq ... INPUT > INPUT.tmp && mv INPUT.tmp INPUT

もう 1 つは、spongeユーティリティ (GNU の一部moreutils)を使用することです。

jq ... INPUT | sponge INPUT

3 番目のオプションは、変更がない場合にファイルを更新しない方が有利な場合に役立ちます。このような機能を説明するスクリプトを次に示します。

#!/bin/bash

function maybeupdate {
    local f="$1"
    cmp -s "$f" "$f.tmp"
    if [ $? = 0 ] ; then
      /bin/rm $f.tmp
    else
      /bin/mv "$f.tmp" "$f"
    fi
}

for f
do
    jq . "$f" > "$f.tmp"
    maybeupdate "$f"
done
于 2016-04-12T15:19:51.153 に答える
3

重複した質問に対する私の回答を使用する

.Actions割り当ては、割り当てが実行されたオブジェクト全体を出力するため、変更された Actions 配列に新しい値を割り当てることができます

.Actions=([.Actions[] | if .properties.age == "3" then .properties.other = "no-test" else . end])

if ステートメントを使用しましたが、コードを使用して同じことを行うことができます

.Actions=[.Actions[] | select (.properties.age == "3").properties.other = "no-test"]

上記は、.Actions編集されたjson全体を出力します。jq には同様の機能はありませんでしたが、ファイルにスポンジsed -iに戻すだけで済みます。| sponge

 jq '.Actions=([.Actions[] | if .properties.age == "3" then .properties.other = "no-test" else . end])' sample.json | sponge sample.json
于 2016-04-15T19:50:40.467 に答える
1

ティーコマンドを使用する

➜ cat config.json|jq '.Actions[] | select (.properties.age == "3") .properties.other = "no-test"'|tee config.json
{
  "value": "1",
  "properties": {
    "name": "abc",
    "age": "2",
    "other ": "test1"
  }
}
{
  "value": "2",
  "properties": {
    "name": "def",
    "age": "3",
    "other": "no-test"
  }
}

➜ cat config.json
{
  "value": "1",
  "properties": {
    "name": "abc",
    "age": "2",
    "other ": "test1"
  }
}
{
  "value": "2",
  "properties": {
    "name": "def",
    "age": "3",
    "other": "no-test"
  }
}
于 2021-10-28T10:52:10.143 に答える