Alak
Alak

Reputation: 1349

Sed regex replace

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

Answers (3)

Avinash Raj
Avinash Raj

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

Tudor Berariu
Tudor Berariu

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

Mike H-R
Mike H-R

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

Related Questions