jqを使用してjsonファイルの値を置き換えて内容全体を返す方法

jqを使用してjsonファイルの値を置き換えて内容全体を返す方法

私はこのようなJSONを持っています

{
  "AgentGroupId": null,
  "AgentId": null,
  "CreateType": "Website",
  "IsPrimary": true,
  "IsShared": true,
  "HeaderAuthentication": {
    "Headers": [
      {
        "Name": "api-key",
        "Value": "TEST_API_KEY_VALUE-2",
        "OriginalName": null,
        "IsReplacedCredentials": false
      },
      {
        "Name": "Authorization",
        "Value": "",
        "OriginalName": null,
        "IsReplacedCredentials": false
      }
    ],
    "IsEnabled": true
  },
  "IsTimeWindowEnabled": false,
  "AdditionalWebsites": [],
  "BasicAuthenticationApiModel": {
    "Credentials": null,
    "IsEnabled": false,
    "NoChallenge": false
  },
  "ClientCertificateAuthenticationSetting": null,
  "Cookies": null,
  "CrawlAndAttack": true,
  "EnableHeuristicChecksInCustomUrlRewrite": true,
  "ExcludedLinks": [
    {
      "RegexPattern": "gtm\\.js"
    },
    {
      "RegexPattern": "WebResource\\.axd"
    },
    {
      "RegexPattern": "ScriptResource\\.axd"
    }
  ],
  "ExcludedUsageTrackers": [],
  "DisallowedHttpMethods": [],
  "ExcludeLinks": true,
  "ExcludeAuthenticationPages": false,
  "FindAndFollowNewLinks": true,
  "FormAuthenticationSettingModel": {
    "Integrations": {},
    "CustomScripts": [],
    "InteractiveLoginRequired": false,
    "DefaultPersonaValidation": null,
    "DetectBearerToken": true,
    "DisableLogoutDetection": false,
    "IsEnabled": false,
    "LoginFormUrl": null,
    "LoginRequiredUrl": null,
    "LogoutKeywordPatterns": null,
    "LogoutKeywordPatternsValue": null,
    "LogoutRedirectPattern": null,
    "OverrideTargetUrl": false,
    "Personas": [],
    "PersonasValidation": null
  }
}

api-key私の目標は、アンダーの値を変更することですHeaderAuthentication(インデックス0、1、2、または他の可能性があります)。

私はこれをしました

jq '.HeaderAuthentication.Headers[] | select(.Name == "api-key") | .Value = "xxx"' scanprofile.json > tmp && mv tmp scanprofile.json

問題はjq置き換えられた部分だけが返されたようですが、ファイル全体が必要ですが、何が間違っているのでしょうか。

コマンドを実行した後のファイルの内容。

{
  "Name": "api-key",
  "Value": "xxx",
  "OriginalName": null,
  "IsReplacedCredentials": false
}

PS:スポンジを使ったスタックオーバーフローの投稿を見ましたが、私たちの環境ではスポンジを使用することはできません。

答え1

表現jq方式

.HeaderAuthentication.Headers[] | select(.Name == "api-key")

値をHeaders含む配列要素を選択します。api-keyName

表現方式

(.HeaderAuthentication.Headers[] | select(.Name == "api-key")).Value |= "NEW VALUE"

この配列要素のキー値をValueリテラル文字列で更新しますNEW VALUE

コマンドラインで新しい値を保持するシェル変数を使用します。

new_api_key='My new key'
jq --arg newkey "$new_api_key" '(.HeaderAuthentication.Headers[] | select(.Name == "api-key")).Value |= $newkey' file.json

キーをBase64でエンコードする必要がある場合は、($newkey|@base64)式の値で更新してください。$newkeyjq

変更するには、次のようなものを使用してください。

tmpfile=$(mktemp)
cp file.json "$tmpfile" &&
jq --arg ...as above... "$tmpfile" >file.json &&
rm -f -- "$tmpfile"

または、元のファイルの権限、所有権などを維持する必要がない場合

tmpfile=$(mktemp)
jq --arg ...as above... file.json >"$tmpfile" &&
mv -- "$tmpfile" file.json

答え2

次は動作します。

tmp=$(mktemp /tmp/tmp.XXXXXXX)
jq  '(.HeaderAuthentication.Headers[] | select(.Name == "api-key") | .Value) = "xxx"' scanprofile.json  > "$tmp" && mv "$tmp"  scanprofile.json

もう一つの方法は、次を使用することです。

cat <<< $(jq '(.HeaderAuthentication.Headers[] | select(.Name == "api-key") | .Value) = "xxx"' scanprofile.json ) > scanprofile.json

catここでは、変更された出力をファイルに直接送信するために使用します。

括弧内にグループ化する必要があります。

関連情報