更改与条件匹配的JSON列表中的条目,而不丢弃其他文档

时间:2018-08-02 16:40:13

标签: json bash edit jq

我试图打开一个文件,浏览该文件并根据该值更改一个值,然后将其传递给文件或var。 以下是JSON的示例

public after(data: IResult) {
  const result: Body = data["soapenv:Envelope"]["soapenv:Body"];
  return result;
}

我一直在使用jq,并且成功隔离了对象组并更改了值。

{
     "Par": [
         {
             "Key": "12345L",
             "Value": "https://100.100.100.100:100",
             "UseLastValue": true
         },
         {
             "Key": "12345S",
             "Value": "VAL2CHANGE",
             "UseLastValue": true
         },
         {
             "Key": "12345T",
             "Value": "HAPPY-HELLO",
             "UseLastValue": true
         }
     ],
      "CANCOPY": false,
      "LOGFILE": ["HELPLOG"]
 }

这给

 cat jsonfile,json | jq '.Par | map(select(.Value=="VAL2CHANGE")) | .[] | .Value="VALHASBEENCHANGED"'

想要实现的id是保留更改后的值的完整JSON输出

         {
             "Key": "12345S",
             "Value": "VALHASBEENCHANGED",
             "UseLastValue": true
         }

I.E。

{
     "Par": [
         {
             "Key": "12345L",
             "Value": "https://100.100.100.100:100",
             "UseLastValue": true
         },
         {
             "Key": "12345S",
             "Value": "VALHASBEENCHANGED",
             "UseLastValue": true
         },
         {
             "Key": "12345T",
             "Value": "HAPPY-HELLO",
             "UseLastValue": true
         }
     ],
      "CANCOPY": false,
      "LOGFILE": ["HELPLOG"]
 }

OR

打开文件,在文件中查找,更改文件的值并将其更改并输出到文件或屏幕上

要添加,json文件将仅包含im创建一次时查找一次的值。如果需要更改任何其他值,我将使用不同的名称。

2 个答案:

答案 0 :(得分:4)

jq --arg match "VAL2CHANGE" \
   --arg replace "VALHASBEENCHANGED" \
  '.Par |= map(if .Value == $match then (.Value=$replace) else . end)' \
  <in.json

要更全面地在嵌套数据结构中的任意位置替换字符串,可以使用walk函数-该函数将在jq 1.6的标准库中提供,但可以在1.5中手动将其引入:

jq --arg match "VAL2CHANGE" \
   --arg replace "VALHASBEENCHANGED" '

# taken from jq 1.6; will not be needed here after that version is released.
# Apply f to composite entities recursively, and to atoms
def walk(f):
  . as $in
  | if type == "object" then
      reduce keys_unsorted[] as $key
        ( {}; . + { ($key):  ($in[$key] | walk(f)) } ) | f
  elif type == "array" then map( walk(f) ) | f
  else f
  end;

walk(if . == $match then $replace else . end)' <in.json

答案 1 :(得分:3)

如果您只是根据值进行替换,则可以流式传输文件并在重建结果时替换值。

$ jq --arg change 'VAL2CHANGE' --arg value 'VALHASBEENCHANGED' -n --stream '
fromstream(inputs | if length == 2 and .[1] == $change then .[1] = $value else . end)
' input.json