Reputation: 1349
I try to use sed to find and replace a value for given key in a json :
myfile.json :
"firstKey" : "firstValue", "key" : "valueToReplace", "otherKey" : "otherValue",
The sed command I try :
sed 's/"key" : ".*",/"key" : "NewValue",/' myfile.json
The result I have with this :
"firstKey" : "firstValue", "key" : "NewValue",
Any idea, how can I match the first next occurrence of
",
instead of the last occurrence ?
Upvotes: 1
Views: 566
Reputation: 174696
You could try this GNU sed command also,
sed -r 's/(\"key\" : )\"[^,]*/\1"Newvalue"/g' file.json
Example:
$ echo '"firstKey" : "firstValue", "key" : "valueToReplace", "otherKey" : "otherValue",' | sed -r 's/(\"key\" : )\"[^,]*/\1"Newvalue"/g'
"firstKey" : "firstValue", "key" : "Newvalue", "otherKey" : "otherValue",
Upvotes: 1
Reputation: 4910
There is another interesting aspect here: escaping double quotes. Maybe your values can contain the "
character. You might want to include \"
or ""
in your string:
sed 's/"key" : "\([^"]\|\(""\)\|\(\\"\)\)*",/"key" : "NewValue",/' myfile.json
Basically you match every character that is not "
or any ""
sequence or any \"
sequence before reaching the closing double quotes.
Upvotes: 0
Reputation: 7815
There are two things you should be doing, you should use a non-greedy regex (.*?
) this is a useful thing to do in many situations and I would recommend using it as standard (in general you will want the non-greedy option more often than the greedy option).
This would make the resulting sed command:
sed 's/"key" : ".*?",/"key" : "NewValue",/' myfile.json
however, that still isn't a great solution, it will do what you want but I find it is better to think about what your regex is saying. With ".*?"
you are saying a quote followed by zero or more of everything until another quote and pick the first one (lazy). However, that is not exactly what you want, you do not want there to be a quote in that group so using a negative capture group would be best. (it is usually good practice to exclude things from capture groups and restrict it to only what you need. This makes clearer, more stable and more reusable regexes). This was pointed out in the comments and gives:
sed 's/"key" : "[^"]*?",/"key" : "NewValue",/' myfile.json
Upvotes: 0