0

I have one file having following example text.

"list-value": {
    "object-value": {
      "value": "example-value-123"
    }
 }

I want to change value text "example-value-123" by matching pattern from list-value with value text "example-value-changed-567"

Example

 "list-value": {
        "object-value": {
          "value": "example-value-changed-567"
        }
     }

I don't want to match text pattern starting from value. I have to match pattern starting from list value. I have tried to create regular expression but not able to match pattern after new line found.

Regular expression I have tried so far

 $ sed -i 's/ [[:space:]]\"list-value\":[[:space:]]{[[:space:]]N;[[:space:]]\"objet-value\"[[:space:]]:[[:space:]]\"[\w+\W+]+\"[[:space:]]} / [[:space:]]\"list-value\":[[:space:]]{[[:space:]]N;[[:space:]]\"objet-value\"[[:space:]]:[[:space:]]\"example-value-changed-567\"[[:space:]]}/g' file.json

I am getting below error for above command

sed: 1: "file. ...": command a expects \ followed by text

I have created one regular expression online but it is not woking with sed command.

\s+"list-value":\s+{\s+"value"\s*:\s+"[\w+\W+]+"\s+}

I need to find better and working regular expression for sed command.

2
  • You never mention what you want to do with this JSON document, or whether this is the complete document (it looks malformed since there's no enclosing {...}). You also fail to say in what way your attempt failed.
    – Kusalananda
    Commented Jan 11, 2019 at 9:42
  • @Kusalananda I have updated the Question Commented Jan 11, 2019 at 9:48

3 Answers 3

2

Assuming that the JSON document is properly formatted, as

{
  "list-value": {
    "object-value": {
      "value": "example-value-123"
    }
  }
}

jq may be used to modify the value:

$ jq '."list-value"."object-value".value="example-value-changed-567"' file.json
{
  "list-value": {
    "object-value": {
      "value": "example-value-changed-567"
    }
  }
}

The result may be redirected to a new file and that file could replace the original file if you wished to change that:

tmpfile=$(mktemp)
cp file.json "$tmpfile"
jq '."list-value"."object-value".value="example-value-changed-567"' "$tmpfile" >file.json
rm "$tmpfile"

I'd avoid parsing a structured document format like JSON (or XML, YAML, HTML etc.) with a line-oriented tool like sed. If there is a parser for the format that you can use, then use that instead. Parsers for JSON are available in all major programming languages. This makes your code more robust as you don't have to care about the actual formatting or character encoding used in the input data. Note, for example, that your document is equivalent to

{ "list-value": {
    "object-value": { "value": 
"example-value-123"
    }
  }
}
2

I think you're looking for this as a sed command:

sed -i.backup '/list-value/{N;N;s/example-value-123/example-value-changed-567/}' file.json

Example:

$ cat ./file.json
"list-value": {
    "object-value": {
        "value": "example-value-123"
    }
}
"list-value-2": {
    "object-value": {
        "value": "example-value-123"
    }
}

# please note this creates a backup file: file.json.backup
$ sed -i.backup '/list-value/{N;N;s/example-value-123/example-value-changed-567/}' file.json

$ cat ./file.json
"list-value": {
    "object-value": {
        "value": "example-value-changed-567"
    }
}
"list-value-2": {
    "object-value": {
        "value": "example-value-123"
    }
}
0

Nested structures, namely JSON, must be processed by structure aware (here JSON) routines. Whenever you attempt processing it via (multi) line-aware only routines, you'll be always exposed to false-positives.

Thus, your ask (again, asusminig it's properly formed JSON) is easily achievable via jtc:

bash $ jtc -w'[list-value]<value>l' -u'"example-value-changed-567"' file.json
{
   "list-value": {
      "object-value": {
         "value": "example-value-changed-567"
      }
   }
}
bash $ 

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .