jsonsedreplace

How can I use sed to replace specific characters within a substring between delimiters?


I need to process a large json file, in which I need to change hyphens to underscore in values of a specific key, for example within the file I would change:

{
  "key": ["test-value-1", "value-2"],
  "anotherKey": "unrelated-value"
}

to:

{
  "key": ["test_value_1", "value_2"],
  "anotherKey": "unrelated-value"
}

without modifying the values of other keys. I think the problem can be generalised to replacing all the occurrences of a specific character between delimiters, in my case:

How can I achieve that using sed?

Note: I am using a macos, not sure if that matters.

So far I have managed to replace the entire value list with:

sed -E 's/"key": \[(.*)\]/"key": \["replaced_value"\]/'

for example:

$ echo '{"key": ["test-value-1", "value-2"], "anotherKey": "unrelated-value"}' | sed -E 's/"key": \[(.*)\]/"key": \["replaced_value"\]/'
{"key": ["replaced_value"], "anotherKey": "unrelated-value"}

I am not sure how to further operate on the value captured with the regular expression to replace only specific character within it.


Solution

  • You can just let replace all - with _ where the line contains "key"::

    sed '/"key":/ s/-/_/g' /tmp/json
    

    But using this is much more safer / easier with gsub:

    jq '.key[] |= gsub("-"; "_")' /tmp/json
    

    Online Demo


    Both produce:

    {
      "key": ["test_value_1", "value_2"],
      "anotherKey": "unrelated-value"
    }